我在spring / spring-mvc中有一个完全使用JSON通信的应用程序。现在,我需要通过JSON使用Spring Security 3(使用LdapAuthenticationProvider)对我的应用程序进行身份验证。
默认的spring seurity提交表单需要这样的POST:
POST /myapp/j_spring_security_check HTTP/1.1 Accept-Encoding: gzip,deflate Content-Type: application/x-www-form-urlencoded Content-Length: 32 Host: 127.0.0.1:8080 Connection: Keep-Alive User-Agent: Apache-HttpClient/4.1.1 (java 1.5) j_username=myUsername&j_password=myPass
但我想像这样传递一个JSON对象:
{"j_username":"myUsername","j_password":"myPass"}
我看了很多帖子喜欢这样,这样其他的或这一个没有运气,在所有的Ajax的情况下完成一个POST像上面。
有任何想法吗?
目标是授予传统浏览器形式的POST身份验证和基于JSON的身份验证。同样在JSON身份验证中,我想避免重定向到loginSuccesful.htm
在上下文中:
<security:http use-expressions="true" auto-config="false" entry-point-ref="http403EntryPoint"> <security:intercept-url pattern="/logs/**" access="denyAll" /> <!-- ... All other intercept URL --> <security:custom-filter ref="CustomUsernamePasswordAuthenticationFilter" position="FORM_LOGIN_FILTER "/> <security:logout invalidate-session="true" logout-success-url="/LogoutSuccessful.htm" delete-cookies="true" /> <security:session-management> <security:concurrency-control max-sessions="1" error-if-maximum-exceeded="true" /> </security:session-management> <security:access-denied-handler error-page="/accessDenied.htm" /> </security:http> <bean id="CustomUsernamePasswordAuthenticationFilter" class="path.to.CustomUsernamePasswordAuthenticationFilter"> <property name="authenticationManager" ref="authenticationManager" /> <property name="authenticationSuccessHandler" ref="customSuccessHandler"/> <property name="authenticationFailureHandler" ref="failureHandler"/> <property name="filterProcessesUrl" value="/j_spring_security_check"/> <property name="usernameParameter" value="j_username"/> <property name="passwordParameter" value="j_password"/> </bean> <bean id="customSuccessHandler" class="path.to.CustomAuthenticationSuccessHandler"> <property name="defaultTargetUrl" value="/login.htm" /> <property name="targetUrlParameter" value="/LoginSuccessful.htm" /> </bean> <bean id="failureHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler"> <property name="defaultFailureUrl" value="/login.htm" /> </bean> <bean id="http403EntryPoint" class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint" />
CustomUsernamePasswordAuthenticationFilter类:
public class CustomUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter{ private String jsonUsername; private String jsonPassword; @Override protected String obtainPassword(HttpServletRequest request) { String password = null; if ("application/json".equals(request.getHeader("Content-Type"))) { password = this.jsonPassword; }else{ password = super.obtainPassword(request); } return password; } @Override protected String obtainUsername(HttpServletRequest request){ String username = null; if ("application/json".equals(request.getHeader("Content-Type"))) { username = this.jsonUsername; }else{ username = super.obtainUsername(request); } return username; } @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response){ if ("application/json".equals(request.getHeader("Content-Type"))) { try { /* * HttpServletRequest can be read only once */ StringBuffer sb = new StringBuffer(); String line = null; BufferedReader reader = request.getReader(); while ((line = reader.readLine()) != null){ sb.append(line); } //json transformation ObjectMapper mapper = new ObjectMapper(); LoginRequest loginRequest = mapper.readValue(sb.toString(), LoginRequest.class); this.jsonUsername = loginRequest.getUsername(); this.jsonPassword = loginRequest.getPassword(); } catch (Exception e) { e.printStackTrace(); } } return super.attemptAuthentication(request, response); } }
CustomAuthenticationSuccessHandler类:
public class CustomAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler { public void onAuthenticationSuccess( HttpServletRequest request, HttpServletResponse response, Authentication auth )throws IOException, ServletException { if ("application/json".equals(request.getHeader("Content-Type"))) { /* * USED if you want to AVOID redirect to LoginSuccessful.htm in JSON authentication */ response.getWriter().print("{\"responseCode\":\"SUCCESS\"}"); response.getWriter().flush(); } else { super.onAuthenticationSuccess(request, response, auth); } } }