无法验证CSRF令牌! Angular 2&春天安全

时间:2016-11-07 13:41:20

标签: java spring servlets angular spring-security

我们正在尝试使用angular 2和spring security实现简单的用户登录。但是我们回复了403状态:

  

{“timestamp”:1478525053048,“status”:403,“error”:“Forbidden”,“message”:“无法验证提供的CSRF令牌,因为找不到您的会话。”,“path”:“ /登录“}

的login.html:

<form>
<div class="form-group">
    <hr>
  <label>Username:</label>
  <input class="form-control input-sm" id="user" type="text" name="user" [(ngModel)]="loginData.user" required><br>
</div>
<div class="form-group">
  <label>Passwort:</label>
  <input class="form-control input-sm" id="password" type="password" name="password" [(ngModel)]="loginData.passwordLogin" required>
</div>
<!--<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" />-->
<input type="submit" value="Login" class="btn btn-default" (click)="login()">

HTTP-service.ts:

    login(username, pwd){
    console.log(username, pwd);
    var json = JSON.stringify({'password':pwd,'username':username});
    var headers = new Headers();
    headers.append('Content-Type','application/json');
    headers.append('authorization', 'Basic');
    return this._http.post('http://localhost:8080/login', json, {
        headers: headers
    }).map(res => res.json());
}

SecurityConfiguration.java:

@EnableWebSecurity
@Configuration
// @Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
    System.out.println("loaded config");
    http.httpBasic() //
            .and() //
            .authorizeRequests() //
            .antMatchers("/login").permitAll() //
            .anyRequest().authenticated() //
            .and().formLogin().loginPage("http://localhost:3000/login")//
            .loginProcessingUrl("/login")//
            .successHandler(successHandler()).failureHandler(failureHandler()).and()//
            .addFilterAfter(new CsrfHeaderFilter(), CsrfFilter.class).csrf()//
            .csrfTokenRepository(csrfTokenRepository());//
}

private CsrfTokenRepository csrfTokenRepository() {
    final HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
    repository.setSessionAttributeName("_csrf");
    repository.setHeaderName("X-XSRF-TOKEN");
    return repository;
}

private AuthenticationSuccessHandler successHandler() {
    return new AuthenticationSuccessHandler() {
        @Override
        public void onAuthenticationSuccess(HttpServletRequest httpServletRequest,
                HttpServletResponse httpServletResponse, Authentication authentication)
                throws IOException, ServletException {
            httpServletResponse.getWriter().append("OK");
            httpServletResponse.setStatus(200);
        }
    };
}

private AuthenticationFailureHandler failureHandler() {
    return new AuthenticationFailureHandler() {
        @Override
        public void onAuthenticationFailure(HttpServletRequest httpServletRequest,
                HttpServletResponse httpServletResponse, AuthenticationException e)
                throws IOException, ServletException {
            httpServletResponse.getWriter().append("Authentication failure");
            httpServletResponse.setStatus(401);
        }

    };
}

CsrfHeaderFilter.java:

public class CsrfHeaderFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
        throws ServletException, IOException {
    final CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
    if (csrf != null) {
        Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
        final String token = csrf.getToken();
        if (cookie == null || token != null && !token.equals(cookie.getValue())) {
            cookie = new Cookie("XSRF-TOKEN", token);
            cookie.setPath("/");
            response.addCookie(cookie);
        }
    }
    filterChain.doFilter(request, response);
}

}

电话: Headers etc.

loadOfLogin

2 个答案:

答案 0 :(得分:0)

如果您要将项目划分为可由Javascript Web服务器托管的前端项目(AngularJS)以及后端(Spring / Java)项目,

您应该开始考虑使用OAuth2安全性而不是常规的Spring安全性。

OAuth2将根据授权规则为您的前端提供与其他服务安全通信的能力。代表您的最终用户。

这也将仅在前端AngularJS方面保留CSRF保护,而无需跨越Java Spring。

答案 1 :(得分:-1)

我建议使用JWT进行Angular 2和spring boot的无状态身份验证。设置角度边的简单方法:

http://jasonwatmore.com/post/2016/08/16/angular-2-jwt-authentication-example-tutorial

对于spring boot,你可以生成一个spring boot示例的脚手架,它拥有来自java hipster的jwt安全性: https://jhipster.github.io/