【问题标题】:Configure Spring security for Angular 2为 Angular 2 配置 Spring 安全性
【发布时间】: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 代码中没有发现任何问题。

标签: angular spring-security


【解决方案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 之类的方式进行不同的身份验证。
猜你喜欢
  • 2023-04-04
  • 2015-04-26
  • 2019-04-03
  • 2016-07-18
  • 2015-11-18
  • 2015-12-02
  • 1970-01-01
  • 2017-02-09
  • 2018-10-07
相关资源
最近更新 更多