使用Ajax登录Spring安全性

Ume*_*thi 5 spring spring-mvc spring-security

我正在尝试使用Spring Security处理基于Ajax的登录系统并且它工作正常,直到我得到了我需要配置的另一个需求authentication-success-handler,因此一旦用户通过Spring安全性进行身份验证,我就可以进行一些后期处理.

之前我没有<form-login/>用于显示登录页面.我的登录部分是一个下拉列表,它是标题部分的一部分,对于整个应用程序是常见的.

这就是我尝试配置Spring安全性的方法

<http pattern="/customer/**" auto-config="true" use-expressions="true" authentication-manager-ref="customerAuthenticationManager">
<!--<http pattern="/customer/**" auto-config="true" use-expressions="true">-->
<intercept-url pattern="/customer/logon.html*" access="permitAll" />
<intercept-url pattern="/customer/denied.html" access="permitAll"/>
<intercept-url pattern="/customer" access="hasRole('AUTH_CUSTOMER')" />
<intercept-url pattern="/customer/" access="hasRole('AUTH_CUSTOMER')" />
<intercept-url pattern="/customer/*.html" access="hasRole('AUTH_CUSTOMER')" />
<intercept-url pattern="/customer/*/*.html" access="hasRole('AUTH_CUSTOMER')" />

<form-login login-processing-url="/customer/logon.html" login-page="/shop/home.html" 
authentication-success-handler-ref="webshopAuthenticationSuccessHandler" />

<logout invalidate-session="true" 
   logout-success-url="/customer/home.html" 
    logout-url="/customer/j_spring_security_logout" />
 <access-denied-handler error-page="/customer/denied.html"/>
    </http>
Run Code Online (Sandbox Code Playgroud)

使用这些配置,当我点击具有正确凭据的登录按钮时,我收到HTTP 302错误

http://localhost:8080/shop/customer/logon.html 302 found
Run Code Online (Sandbox Code Playgroud)

不确定我究竟做错了什么?

<form id="login" method="post" accept-charset="UTF-8">
    <input id="userName" type="text" name="userName" size="30" />
    <button type="submit" class="btn">Login</button>
</form>
Run Code Online (Sandbox Code Playgroud)

Ajax代码

 var data = $(this).serializeObject();
  $.ajax({
  'type': 'POST',
  'url': "<c:url value="/customer/logon.html"/>",
   'contentType': 'application/json',
    'data': JSON.stringify(data),
     'dataType': 'json',
....
}}:
Run Code Online (Sandbox Code Playgroud)

登录部分

 Authentication authenticationToken = new UsernamePasswordAuthenticationToken(customer.getUserName(), customer.getPassword());
   try {
       Authentication authentication = customerAuthenticationManager.authenticate(authenticationToken);
        SecurityContextHolder.getContext().setAuthentication(authentication);
        resp.setStatus(AjaxResponse.RESPONSE_STATUS_SUCCESS);
           } catch (AuthenticationException ex) {

            resp.setStatus(AjaxResponse.RESPONSE_STATUS_FAIURE);
   }
Run Code Online (Sandbox Code Playgroud)

有什么投入?经过我所有的努力,我仍然得到302并且具有上述配置,甚至我的logon.html控制器也没有被调用.

我的主要问题是当我使用Spring安全性时

<form-login login-processing-url="/customer/logon.html" login-page="/shop/home.html" 
    authentication-success-handler-ref="webshopAuthenticationSuccessHandler" />
Run Code Online (Sandbox Code Playgroud)

302来自logon.html甚至logon.html控制器没有被触发(放置调试器)

M. *_*num 11

首先,您不需要控制器,弹簧安全处理所有这些.所以放下控制器.

当前的问题是由于您的基于JSON的帖子.这是由处理登录的普通过滤器处理的,但它没有看到j_usernamej_password字段,因此会将(302)重定向到登录页面(在您的情况下/shop/home.html)请求这些字段.

基本上你将数据发布为JSON,而它只是一个ajaxified形式的帖子.这允许你编写一个简单的AuthenticationSuccessHandler东西,当事情没问题时,简单地返回一个401或200状态代码(也许是一个正文).

将你的ajax提交改为这样的东西会让事情发生变化.

var data = $(this).serializeObject();
$.ajax({
    'type': $(this).action,
    'url': $(this).target,
    'data': data
}):
Run Code Online (Sandbox Code Playgroud)

这应该创建一个ajax表单帖子.您可能需要preventDefault()在周围方法中调用以停止实际发布的表单.