【问题标题】:Spring Boot with Application authentication (403 Fobidden) CSRF token was null. Has your session expired?具有应用程序身份验证的 Spring Boot (403 Fobidden) CSRF 令牌为空。你的会话过期了吗?
【发布时间】:2016-01-18 16:22:22
【问题描述】:

我有一个带有 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 令牌空值。

我的 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);
          }
        }

【问题讨论】:

  • 你的客户是什么?只是普通的js客户端还是jsp?
  • Java代码没有jsp!
  • 确认弹窗来自浏览器,所以有客户端。什么是客户?简单的html、js还是一些框架?
  • 我正在尝试访问一个 Html 文件,并且出现了一个确认弹出窗口以进行身份​​验证!当我删除它时,身份验证不会到来,所以它必须来自 spring 框架 org.springframework.bootspring-boot-starter-security

标签: javascript html spring spring-boot


【解决方案1】:

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

我猜这是 Http Basic 的默认浏览器渲染。也许显式禁用 Http Basic 会有所帮助:

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

【讨论】:

  • 没有名为 .httpBasic() 的函数,我无法禁用身份验证并重定向到 HTML 页面
  • 在第一个authorizeRequests之前,可以使用httpBasic方法。
  • 尝试了您的建议,但没有成功!
【解决方案2】:

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

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

如果你不想做下一件事:

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

请说明您请求的页面。如果找不到该页面,浏览器有时会弹出此页面。你需要解释更多你想要完成的事情,页面本身是什么,请求是什么等等。

【讨论】:

    【解决方案3】:

    以下代码解决了这个问题。删除 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();
    

    【讨论】:

      【解决方案4】:

      就我而言,我在 app 目录下有 js 文件。这个目录抛出了 403

      添加以下代码有帮助。

      .antMatchers("/static/**", "/app/**").permitAll()

      【讨论】:

        猜你喜欢
        • 2016-03-21
        • 2016-03-13
        • 2015-12-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-02-16
        • 1970-01-01
        • 2015-10-09
        相关资源
        最近更新 更多