spring security ajax登录

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring security ajax登录相关的知识,希望对你有一定的参考价值。

我想在spring security 中实现ajax登录,但是j_spring_security_check处理后返回的是跳到其他页面,怎么样让其返回json?网上是说是设置header,如下:
$.ajax(
method:"POST",
url:"j_spring_security_check",
data: $("#login_form").serialize(),
type:"application/json",
beforeSend: function (xhr)
xhr.setRequestHeader("X-Ajax-call", "true");
,
success:function(data)
alert(data);
,
error:function(error)
alert(error);


)

参考技术A 那你需要写自定义的登录action,然后用ajax调用该Action,如果要用到SS机制,请配置SS的相关文件,form-login里面,可以配置成功跳转界面为你自定义的那个Action,就OK了

如何在 Grails 和 AngularJS 上使用 Spring Security 进行 Ajax 登录

【中文标题】如何在 Grails 和 AngularJS 上使用 Spring Security 进行 Ajax 登录【英文标题】:How to do Ajax login with Spring Security on Grails and AngularJS 【发布时间】:2015-12-30 20:13:58 【问题描述】:

我正在尝试创建向服务器发送 Ajax 请求以进行登录的用户表单。

我来自 Angular 的 POST 函数如下所示:

$http(
    method: 'POST',
    url: '/j_spring_security_check',
    data: j_username: credentials.username, j_password: credentials.password,
    params: ajax: true
)
    .then(function (data) 
        $rootScope.authenticated = false;
        callback && callback();
    ,
    function (error) 
        $log.error("Error in login! " + JSON.stringify(error));
        $rootScope.authenticated = false;
        callback && callback();
    );

application.yml 我得到了 Spring Security 的这个配置:

grails:
  plugin:
    springsecurity:
      userLookup:
        userDomainClassName: xxx.LoginUser
      rejectIfNoRule: true
      fii:
        rejectPublicInvocations: false
      controllerAnnotations:
        staticRules:
          [...]

当我调用我的函数并将请求发送到服务器时出现问题。 Spring Security 不接受 mu j_usernamej_password 并且总是返回带有状态 200 和错误文本 "error":"Sorry, we were not able to find a user with that username and password." 的响应

PS 我正在为 Grails (3.0.4) 使用 Spring Security 插件http://grails-plugins.github.io/grails-spring-security-core/guide/index.html

【问题讨论】:

【参考方案1】:

所以这就是问题所在。 Spring Security 插件仅接受带有数据作为查询字符串的POST 请求,当我们通过 Angular 的 $http 调用在 POST 请求中传递一些数据时,它会在请求有效负载正文中发送数据,这会破坏登录,并且您会收到没有用户的消息找到了。

所以第一种方法是使用$httpusernamepassword 作为params 传递:

$http(
    method: 'POST',
    url: '/j_spring_security_check',
    params: j_username: credentials.username, j_password: credentials.password, ajax: true
)

上述方法可以正常工作,但问题是用户名和密码将在查询字符串中发送,因此任何人都可以轻松地在浏览器控制台中读取,因为它不受保护。此外,由于这将作为查询字符串参数传递,因此密码将被记录在各种级别,例如 Tomcat 的 localhost 日志或 Nginx 日志。

要解决此问题,请按以下方式更改您的代码:

var data = 'j_username=' + credentials.username + '&j_password=' + credentials.password;

$http(
    method: 'POST',
    url: '@/j_spring_security_check',
    data: data,
    headers: 
        'Content-Type': 'application/x-www-form-urlencoded'
    
)

所以我们在这里所做的是将凭据作为发布数据发送,并以编程方式更改 Content-Type,以便 Angular 可以将其作为发布数据而不是 JSON 发送。

注意:附加建议:Grails request 属性 request.xhr 不会告诉您通过 Angular 发出的请求是 AJAX 请求,因为 Angular 不会发送任何请求标头以使其工作就像 Grails 的 AJAX。所以添加以下代码:

var myApp = angular.module('myApp', []);             // Or whatever your app name is

myApp.run(['$http', function ($http) 
    $http.defaults.headers.common['x-requested-with'] = 'XMLHttpRequest';
]);

现在您不必在 Angular $http 调用中传递 ajax: true

【讨论】:

感谢您提供有关 xhr 属性的说明,我正在对此进行调查。很高兴知道这是预期的行为,我将添加标头,以便让 Grails 区分每种类型的请求 :)

以上是关于spring security ajax登录的主要内容,如果未能解决你的问题,请参考以下文章

Spring Security Ajax 登录

Spring Security Ajax 登录

spring security为不同用户显示各自的登录成功页面

如何在 Grails 和 AngularJS 上使用 Spring Security 进行 Ajax 登录

spring security 在使用 AJAX 登录时显示 403 错误

Spring Security Ajax 登录在以下请求中成功验证 null