使用应用程序身份验证的Spring Boot(403 Fobidden)CSRF令牌为空。你的会话已经过期了吗?

时间:2016-01-18 16:22:23

标签: javascript html spring spring-boot

我有一个带有thymeleaf模板的Spring Boot应用程序,并使用带有AngularJS的HTML作为我的前端,mysql为DATABASE,数据以JSON传递

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4">
<head>
    <meta name="_csrf" content="${_csrf.token}"/>   
    <meta name="_csrf_header" content="${_csrf.headerName}"/>
</head>

我的JS文件将哪个值发布到:

$scope.logincheck = function() {

var dataObj = {
        userId : $scope.userId,
        password : $scope.password
};

var res = $http.post('http://localhost:9393/company/login', dataObj);

和处理mysql身份验证的相应控制器:

@RequestMapping(value = "/company/login", method = RequestMethod.POST)
如果启用CSRF,

不会被调用。启用CSRF后,我收到403错误,说找到了CSRF令牌null。

我的webconfig.java:

@Override
    protected void configure(HttpSecurity http) throws Exception {

        http 
            .addFilterAfter(new CsrfHeaderFilter(), CsrfFilter.class)
            .authorizeRequests()
            .antMatchers("/resources/**").permitAll()
            .antMatchers("/", "/login").permitAll()
                .antMatchers("/hello").access("hasRole('ADMIN')")
                .anyRequest().authenticated()
                .and()
            .formLogin()
                .loginPage("/login")
                .permitAll()
                .and()
            .logout()
            .logoutUrl("/logout")
            .logoutSuccessUrl("/login")
            .permitAll()
            .and()
            .exceptionHandling().accessDeniedPage("/accessdenied")
            .and()
            .csrf()
            .csrfTokenRepository(csrfTokenRepository());
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .inMemoryAuthentication()
                .withUser("user").password("password").roles("ADMIN")
    }

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

    public class CsrfHeaderFilter extends OncePerRequestFilter {
          @Override
          protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
              throws ServletException, IOException {
              System.out.println("Inside Webappconfig.java");
            CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
            if (csrf != null) {
              Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
              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);
          }
        }

4 个答案:

答案 0 :(得分:0)

  

使用上面的代码,我得到一个确认对话框 ...

我猜这是 Http Basic 的默认浏览器呈现。也许禁用Http Basic有助于:

protected void configure(HttpSecurity http) throws Exception {
          http
              .httpBasic().disable()
          ...
}

答案 1 :(得分:0)

你做错了。如果只是简单的html,一旦你想访问页面,它就会受到限制,这就是浏览器弹出的原因。

我建议使用一些模板从这里复制demo: http://docs.spring.io/spring-security/site/docs/3.2.x/guides/form.html

如果你不想做下一件事:

http
    .authorizeRequests()
        .anyRequest().authenticated()
        .and()
    .formLogin()
        .and()
    .httpBasic().disable();

请说明您要求的页面。如果找不到页面,浏览器有时可以执行此弹出窗口。您需要解释更多您想要完成的内容以及页面本身是什么,请求是什么等等。

答案 2 :(得分:0)

以下代码解决了问题。删除httpBasic()函数的最后一行做了伎俩。谢谢大家。

.authorizeRequests()
.antMatchers("/index.html", "/home.html", "/login.html", "/").permitAll()
          .anyRequest().authenticated()
          .and()
           //Add this line to remove Authentication through browser problem 
          .formLogin().loginPage("/login").permitAll();

答案 3 :(得分:0)

在我的情况下,我在app dir下有js文件。这个目录投掷了403

添加以下代码有帮助。

.antMatchers(“/ static / **”,“/ app / **”)。permitAll()