Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Grails和AngularJS上使用Spring安全性进行Ajax登录_Ajax_Angularjs_Spring_Grails_Spring Security - Fatal编程技术网

如何在Grails和AngularJS上使用Spring安全性进行Ajax登录

如何在Grails和AngularJS上使用Spring安全性进行Ajax登录,ajax,angularjs,spring,grails,spring-security,Ajax,Angularjs,Spring,Grails,Spring Security,我试图创建一个用户表单,将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)

我试图创建一个用户表单,将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_用户名和j_密码,并始终返回状态为200的响应和错误文本{错误:抱歉,我们无法找到具有该用户名和密码的用户。}

PS
我正在为Grails 3.0.4使用Spring安全插件,所以问题出在这里。Spring安全插件只接受以数据作为查询字符串的POST请求,当我们通过Angular的$http调用传递POST请求中的一些数据时,它会在请求有效负载体中发送数据,这会中断登录,您会收到未找到用户的消息

因此,第一种方法是使用$http将用户名和密码作为参数传递:

上述方法可以正常工作,但问题是用户名和密码将在查询字符串中发送,因此任何人都可以在浏览器控制台中轻松读取,因为它不受保护。此外,由于该密码将作为查询字符串参数传递,因此将在不同级别记录密码,如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'
    }
})
因此,我们在这里所做的是将凭证作为post数据发送,并以编程方式更改内容类型,以便Angular可以将其作为post数据而不是JSON发送

注意:另外一个建议是:Grails request attribute 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区分每种类型的请求:
var myApp = angular.module('myApp', []);             // Or whatever your app name is

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