【发布时间】:2016-08-28 15:15:13
【问题描述】:
我正在使用 AngularJS 实现登录页面,以针对 LDAP 服务器进行身份验证。后端的身份验证由 Spring Security 完成。基本上用户名和密码通过一个 post 请求发送到服务器,该请求由 Spring 处理,没有显式处理程序。
当我提交登录表单时,post 请求返回 302 并根据凭据是否有效重定向到另一个 url。如果密码正确,它将向“http://localhost:8080/”发起GET请求。如果密码错误,它会重定向到“http://localhost:8080/login?error”。这是 Spring Security 的已知行为。根据Dave Syer's article,“Spring Security 默认行为是在成功和失败时发送 302,Angular 将遵循重定向,因此我们必须实际解析来自该响应的响应”。在 Dave 的教程中,他使用辅助函数来验证一般情况下的身份验证。我认为它不适用于 LDAP 身份验证。
我发现了另一个非常相似的帖子Spring Boot and Security with custom AngularJS Login page。虽然它没有官方答案,但根据最后的评论,似乎在 Java 配置中修改 .antMatchers 中的路径可能已经解决了这个问题。但是,我来回使用我的安全配置(见下文),它似乎没有帮助。
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic().and()
.addFilterBefore(new CORSFilter(), ChannelProcessingFilter.class)
.csrf().disable()
.authorizeRequests()
.antMatchers("/login/", "/login","login/")
.permitAll()
.anyRequest()
.authenticated()
.and()
.formLogin();
}
虽然 302 不会产生任何响应,但客户端以某种方式知道根据凭据的有效性重定向到哪个 url。我的理解是服务器必须以“秘密”方式告诉客户端身份验证是否成功。如果我在客户端发送 GET 请求之前捕获并解析这些隐藏信息,我可以使用 Angular 进行身份验证。像这样的东西(部分伪代码):
app.controller("LoginCtrl", ['$scope', '$location',
function($scope, $location){
$scope.authenticate = function() {
loginFactory.login($scope.username, $scope.password) {
// pseudo code starts
if (redirect.path == 'localhost') {
$location.path('/main');
}
else {
$location.path('/loginfail');
console.log("Login failed");
}
}
}]);
问题是如何在重定向发生之前诊断 302 并识别响应的性质?最坏的情况,我可以让重定向开始,并从 GET 请求中获取response.path 并确定登录是否成功。但我尽量不走那条路。非常需要建议。
【问题讨论】:
标签: angularjs login spring-security httprequest