通过使用 AngularJS 的自定义登录进行 Spring Security 身份验证

Posted

技术标签:

【中文标题】通过使用 AngularJS 的自定义登录进行 Spring Security 身份验证【英文标题】:Spring Security authentication through custom login with AngularJS 【发布时间】:2015-10-15 09:03:36 【问题描述】:

我正在使用 AngularJS 前端在我的应用程序中为 Spring Security 创建一个自定义登录表单。我很难弄清楚如何处理身份验证。我找到的所有教程和示例都使用 JSP,我看到了这一点:

<form name='loginForm'
      action="<c:url value='j_spring_security_check' />" method='POST'>

我想知道 Angular 中的等价物是什么。我的配置设置为路由到我的自定义登录页面:

@Configuration
@EnableWebSecurity
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class SecurityConfig extends WebSecurityConfigurerAdapter 

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth)
            throws Exception 
        auth.inMemoryAuthentication().withUser("user").password("pass")
                .roles("USER");
    

    @Override
    protected void configure(HttpSecurity http) throws Exception 

        http.authorizeRequests().anyRequest().authenticated().and().formLogin().loginPage("/login/login.html").permitAll();
    

然后我想我会让我的登录页面在提交用户名/密码时调用一个 Angular 函数submitCredentials(isValid)

<!doctype html>
<html ng-app="app">
    <head>
        <title>Person Login</title>
        <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script>
        <script src="app.js"></script>
    </head>

    <div class="container">
    <body>
        <h1>Person Login</h1>
        <br>
        <div ng-controller="LoginCtrl">
            <form class="form-horizontal" name="loginForm" novalidate>

                <div class="form-group">
                    <label class="col-sm-1 control-label">Username</label>
                    <div class="col-sm-3">
                        <input class="form-control" name="username" type="text" ng-model="user.username">
                    </div>
                </div>

                <div class="form-group">
                    <label class="col-sm-1 control-label">Password</label>
                    <div class="col-sm-3">
                        <input class="form-control" name="password" type="text" ng-model="user.password">
                    </div>
                </div>

                <br><br>

                <button class="btn btn-primary" ng-click="submitCredentials(loginForm.$valid)">
                    Submit
                </button>
            </form>
        </div>
    </body>
    </div>
</html>

然后在控制器中做一些事情:

angular.module('app').controller('LoginCtrl', function($scope, $location, $http, $routeParams) 

    $scope.submitCredentials(isValid) 

        if (isValid) 
            // do something to authenticate user
        
    
);

这是我不知道该怎么做的部分。现在我使用内存中的 Spring 身份验证作为一个简单的开始,所以如果我可以通过自定义登录来实现这一点,我会很高兴。稍后我想通过检查数据库中的凭据来进行身份验证。

【问题讨论】:

这是一个老问题,但我陷入了同样的境地。我不想涉及角度导航等等。有没有简单的方法来做到这一点? 【参考方案1】:

你有两个选择:

    不是完整的单页应用程序

这种方法允许您通过表单和&lt;input type="submit"&gt; 执行 POST 请求,从而刷新页面。使用这种方法,服务器将为您提供带有 cookie 的会话 ID,并且每个下一个请求都将被验证(浏览器会自动将会话 ID 添加到每个请求中)。

    完整的单页应用程序

在这种方法中,您创建自定义AuthenticationFilter,它将从用户(例如从 json 或 xml)获取凭据并对其进行身份验证。使用此“登录”请求,您还应该提供一个令牌来替代会话 ID (cookie)。您必须在每个下一个请求中添加此令牌,以便服务器可以解析用户(在标头中,在查询参数中,在路径参数中)。

我建议阅读这篇文章https://spring.io/guides/tutorials/spring-security-and-angular-js/。应该能解开很多疑惑。

【讨论】:

以上是关于通过使用 AngularJS 的自定义登录进行 Spring Security 身份验证的主要内容,如果未能解决你的问题,请参考以下文章

访问 API 中的自定义标头

AngularJS之登录显示用户名

如何从 AngularJS 中的自定义指令 * 使用自己的范围 * 访问父范围?

剑道树视图Angularjs上的自定义按钮

在 angularjs 的自定义指令的 $watch 中不评估表达式

AngularJS ng-repeat 与表格内的自定义元素呈现奇怪