【问题标题】:Spring Boot, Spring Security and Thymeleaf: Apply CsrfFilter to website with formSpring Boot、Spring Security 和 Thymeleaf:将 CsrfFilter 应用到带有表单的网站
【发布时间】:2015-10-21 20:33:07
【问题描述】:

我正在使用带有 Thymeleaf 的 Spring Security,并希望在同时使用 CSRF 保护的不同站点上创建登录和注册表单。与以下 WebSecurity 配置一样,保护登录站点很容易

@Override
protected void configure(final HttpSecurity http) throws Exception {
    http
            .formLogin()
            .loginPage("/login")
            .permitAll()
            .and()
            .requestMatchers()
            .antMatchers("/login", "/oauth/authorize", "/oauth/confirm_access")
            .and()
            .authorizeRequests()
            .anyRequest()
            .authenticated();
}

Spring 通常支持通过在 configure 方法中构建的 Security Filter Chain 添加 CSRF 保护。此过滤器链包含一个 CSRFFilter,用于添加/评估 CSRF 令牌。然后,此过滤器链将用于上述配置中定义的所有匹配项。获取应用于请求的过滤器的机制可以在方法中找到here

doFilterInternal(ServletRequest, ServletResponse, FilterChain)

问题是,如果我将“/register”站点添加到此配置中,用户首先会被重定向到“/login”站点。如果我不将其添加到上述配置中,则不会应用提到的 FilterChain(因此不会应用 CsrfFilter)。

所以我想要重用“/register”站点的过滤器链中的CsrfFilter,但我不知道该怎么做。

我更喜欢这种方法而不是其他想法,例如按照 herehere 的建议编写自定义 CSRF 过滤器。

【问题讨论】:

    标签: spring-security csrf thymeleaf


    【解决方案1】:

    从所有这些我了解到问题是您希望人们无需先登录即可访问/注册。这是一个简单的修复:

    @Override
    protected void configure(final HttpSecurity http) throws Exception {
        http
                .formLogin()
                .loginPage("/login")
                .permitAll()
                .and()
                .requestMatchers()
    // add this line
    .antMatchers("/register").permitAll().and
    
    //
                .antMatchers("/login", "/oauth/authorize", "/oauth/confirm_access")
                .and()
                .authorizeRequests()
                .anyRequest()
                .authenticated();
    }
    

    【讨论】:

    • 嗨阿瑟尔!那不是问题。我的目标是在我的 /register 表单中启用 CSRF 保护。 Spring 支持通过在 configure 方法中构建的 Security Filter Chain 通常添加 CSRF 保护。此过滤器链包含一个 CSRFFilter,用于添加/评估 CSRF 令牌。如果我按照您建议的方式添加 /register 站点,过滤器链将忽略该站点,因此将不会使用 CSRF 保护。我在帖子中添加的链接建议了添加手动 CSRF 保护机制的方法,但我宁愿重用 Spring 现有的。
    • 我一定是误会了。因此,您创建了一个自定义安全过滤器链而不是使用现有的安全过滤器链,从而导致问题?
    【解决方案2】:

    原来 Spring Security Filter 链适用于提供给 requestMatchers().antMatchers() 的列表中提到的所有端点。

    所以要对不是登录站点的站点使用 CSRF 保护,我只需将其添加到此列表中,然后允许对其进行所有访问,因此不会重定向到登录页面。我的最终配置如下所示

    @Override
    protected void configure(final HttpSecurity http) throws Exception {
        http.requestMatchers()
                // consider these patterns for this config and the Security Filter Chain
                .antMatchers("/login", "/register", "/oauth/authorize", "/oauth/confirm_access", "/oauth/token_key",
                        "/oauth/check_token", "/oauth/error")
                .and()
                // define authorization behaviour
                .authorizeRequests()
                // /register is allowed by anyone
                .antMatchers("/register").permitAll()
                // /oauth/authorize needs authentication; enables redirect to /login
                .antMatchers("/oauth/authorize").authenticated()
                // any other request in the patterns above are forbidden
                .anyRequest().denyAll()
                .and()
                .formLogin()
                // we have a custom login page at /login
                // that is permitted to everyone
                .loginPage("/login").permitAll();
    }
    

    【讨论】:

      猜你喜欢
      • 2018-02-05
      • 2018-01-29
      • 2017-07-22
      • 2017-02-09
      • 2017-10-02
      • 1970-01-01
      • 1970-01-01
      • 2021-01-17
      • 1970-01-01
      相关资源
      最近更新 更多