为 Angular 2 配置 Spring 安全性

Posted

技术标签:

【中文标题】为 Angular 2 配置 Spring 安全性【英文标题】:Configure Spring security for Angular 2 【发布时间】:2017-07-01 19:07:41 【问题描述】:

我正在构建一个 Angular 2 Web 客户端,它尝试使用 SpringBoot Security 对服务器进行 POST。我应该如何编写我的 Spring 安全配置?

我的 Angular 身份验证调用:

public login(username, password) 
  let body = JSON.stringify(username: username, password: password);
  let headers = new Headers('Content-Type': 'application/json');
  let options = new RequestOptions(headers: headers);
  this.http.post("http://localhost:8080/login", body, options)
    .subscribe(
      res => this.loggedIn = true,
      err => console.error("failed authentication: " + err),
      () => console.log("tried authentication")
    );

身份验证失败并出现错误:

"timestamp":1487007177889,"status":401,"error":"Unauthorized","message":"Authentication Failed: Empty Username","path":"/login"

我的spring安全配置:

@Configuration
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter     
    @Autowired
    private RestAuthenticationEntryPoint restAuthenticationEntryPoint;
    @Autowired
    private RestAuthenticationSuccessHandler restAuthenticationSuccessHandler;
    @Autowired
    private RestAuthenticationFailureHandler restAuthenticationFailureHandler;
    @Autowired
    private RestLogoutSuccessHandler restLogoutSuccessHandler;

    @Override
    protected void configure(HttpSecurity http) throws Exception 
        http.csrf().disable()
                .exceptionHandling()
                .authenticationEntryPoint(restAuthenticationEntryPoint)

                .and().formLogin()
                .loginProcessingUrl("/login")
                .usernameParameter("username")
                .passwordParameter("password")
                .successHandler(restAuthenticationSuccessHandler)
                .failureHandler(restAuthenticationFailureHandler)
                .permitAll()

                .and().logout()
                .logoutUrl("/logout")
                .logoutSuccessHandler(restLogoutSuccessHandler)
                .permitAll()

                .and().authorizeRequests().anyRequest().authenticated()
        ;
    

    @Override
    public void configure(AuthenticationManagerBuilder builder) throws Exception 
        // This configuration has been tested, it works.
        // It has been removed for better readability
    

    @Bean
    public LdapContextSource contextSource() 
        // This configuration has been tested, it works.
        // It has been removed for better readability
    

【问题讨论】:

看起来像是 Spring 问题。我在您的 Angular 代码中没有发现任何问题。 【参考方案1】:

您应该使用application/x-www-form-urlencoded 参数进行表单登录,而不是 JSON。这就是错误说用户名丢失的原因,因为 Spring Security 试图从 HttpServletRequest#getParameters 获取它。要在 Angular 中发送表单参数,您可以这样做

import  URLSearchParams  from '@angular/http';

let params = new URLSearchParams();
params.set('username', username);
params.set('password', password);

如果你将它设置为 Http 请求的主体参数,它应该(据我记得)自动被序列化为正确的格式,即

username=xxx&password=xxx

而且我认为您也不需要将标题 Content-Type 设置为 applicatio/x-www-form-urlencoded。我认为当 Angular 检测到 URLSearchParams 作为正文时,也应该为您设置。

【讨论】:

成功了,非常感谢。男人URLSearchParam,什么?这有多直观? 它也用于查询字符串。我想这个名字更有意义 我最后确实使用了headers.append("Content-Type", "application/x-www-form-urlencoded"); 和正文"username=" + username + "&password=" + password。但我认为无论如何我都会使用 Oauth 2 之类的方式进行不同的身份验证。

以上是关于为 Angular 2 配置 Spring 安全性的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 Angular 2 作为前端并使用基本 Http 身份验证获取有关 Spring 安全性的登录详细信息

Spring Boot 提供被安全阻止的静态内容

Angular 2 + CORS + 带有 Spring Security 的 Spring Boot Rest Controller

Spring Boot 安全性:在 Angular 8 中显示登录页面时出现问题

发布请求不适用于 Spring 安全性和 Angular 5

Angular JS 和 Spring 安全 OpenId 集成中的同源策略响应