$ location服务是否覆盖Spring Security登录成功URL?

时间:2017-10-17 08:53:30

标签: angularjs spring-security

我在Spring 3.2中有以下安全配置

.formLogin()
            .loginPage("/login.html")
            .usernameParameter("username").passwordParameter("password")
            .loginProcessingUrl("/perform_login")
            .defaultSuccessUrl("/welcome", false)
            .failureUrl("/notexistpage")

我得出的结论是执行了defaultSuccessUrl()和failureUrl(),加载了相关页面但是Angularjs前端使用ng-route / $ location忽略了。

我在index.html上有一个单页应用程序,它有以下ng-view块,它基本上是一个带登录按钮的bootstrap Nav面板:

<li class="nav-item" ng-show="!authenticated">
                        <a class="nav-link active" id="login-tab" data-toggle="tab" role="tab" aria-controls="login" aria-expanded="true" href="#!/login">Login</a>
                    </li>

<div ng-view class="container"></div>

登录页面会显示在ng-view块上,我有ng-click()函数将表单提交给javascript函数:

$http({
                method: 'POST',
                url: 'perform_login',
                headers: {'Content-Type': 'application/x-www-form-urlencoded'}, 
                transformRequest: function(obj) {
                    var str = [];
                    for(var p in obj)
                    str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
                    return str.join("&");
                },               
                data: credentials
            }).then(function (response) {
                $rootScope.authenticated = true;                
                callback && callback();
            }, function (response) {
                $rootScope.authenticated = false;                
                callback && callback();
            });

根据登录成功/失败,页面会有不同的行为,但仍会返回200/302/304的状态代码,javascript视为成功。此外,登录表单将保留在块中,忽略Java Success Handler。页面确实请求了defaultSuccessUrl()中定义的html,但它没有显示在页面上。

我只能在登录成功后(javascript的第一次回调)硬编码$ location.path(“/”),并强制用户在访问任何页面之前登录。

1 个答案:

答案 0 :(得分:0)

我认为你不能在这里使用Spring Security defaultSuccessUrl。 Webflow的控制应该在客户端上。看看official example,他们也是这样做的。

angular.module('hello', [ 'ngRoute' ]) // ... omitted code
.controller('navigation',

  function($rootScope, $http, $location) {

  var self = this

  var authenticate = function(credentials, callback) {

    var headers = credentials ? {authorization : "Basic "
        + btoa(credentials.username + ":" + credentials.password)
    } : {};

    $http.get('user', {headers : headers}).then(function(response) {
      if (response.data.name) {
        $rootScope.authenticated = true;
      } else {
        $rootScope.authenticated = false;
      }
      callback && callback();
    }, function() {
      $rootScope.authenticated = false;
      callback && callback();
    });

  }

  authenticate();
  self.credentials = {};
  self.login = function() {
      authenticate(self.credentials, function() {
        if ($rootScope.authenticated) {
          $location.path("/");
          self.error = false;
        } else {
          $location.path("/login");
          self.error = true;
        }
      });
  };
});