Spring Boot使用CSRF令牌和BasicAuth保护相同的端点

时间:2018-10-17 12:27:05

标签: spring-security

我有一个Spring Boot REST应用程序,它具有两个主要部分:

  • 我要使用令牌保护ajax调用的UI
  • 我想拥有基本身份验证的
  • 公共端点

据我了解,我无法使用CSRF令牌保护公共端点,因为这些令牌需要会话。问题是,某些端点都需要两者都可以访问,所以当UI使用CSRF并为基本身份验证禁用CSRF时,如何使用CSRF保护它们?

这是我目前拥有的东西,在这里我完全禁用了csrf,因此基本工作原理...

http.requestMatchers().antMatchers("/form/fill", "/form/fill/*", "/form/fillParams", "/form/fillParams/*").and()
                .csrf().disable().authorizeRequests().anyRequest().hasAnyRole(SecurityConfiguration.ROLE_FORMS_AUTHOR,
                        SecurityConfiguration.ROLE_FORM_FILLER, SecurityConfiguration.ROLE_ADMIN)
                .and().httpBasic();

编辑:我找到了this个旧答案,我想知道是否有一种方法可以利用此方法解决我的问题,但是我仍然不确定如何区分“本地”用户和通过httpBasic()认证的

2 个答案:

答案 0 :(得分:1)

在您的Spring Security Java配置文件中,您可以按以下方式配置HttpSecurity对象,以便仅对某些请求启用CSRF检查(默认情况下,所有传入请求均启用,并禁用将对所有传入请求都禁用,因此请求马瑟可以在此处为您要启用或禁用csrf的路径提供帮助。)

请确保通过终点或多条路径将/urls-with-csrf-check/**替换为您的路径。

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

        RequestMatcher csrfRequestMatcher = new RequestMatcher() {
            private RegexRequestMatcher requestMatcher =
                    new RegexRequestMatcher("/urls-with-csrf-check/**", null);

            public boolean matches(HttpServletRequest httpServletRequest) {
                if (requestMatcher.matches(httpServletRequest)) {
                    return true;
                }
                return false;
            }
        };

        http.requestMatchers().antMatchers("/form/fill", "/form/fill/*", "/form/fillParams", "/form/fillParams/*").and()
                .csrf()
                .requireCsrfProtectionMatcher(csrfRequestMatcher)
                .and()
                .authorizeRequests().anyRequest().hasAnyRole(SecurityConfiguration.ROLE_FORMS_AUTHOR, SecurityConfiguration.ROLE_FORM_FILLER, SecurityConfiguration.ROLE_ADMIN)
                .and().httpBasic();
    }

答案 1 :(得分:0)

利用@ kj007的输入,我能够使它工作。 我正在使用requireCsrfProtectionMatcher,这就是我的匹配器的样子:

public class UIRequestMatcher implements RequestMatcher {

    public static final List<GrantedAuthority> USER_ROLES = new ArrayList<>();
    static {
        USER_ROLES.add(new SimpleGrantedAuthority(SecurityConfiguration.ROLE_ADMIN));
        USER_ROLES.add(new SimpleGrantedAuthority(SecurityConfiguration.ROLE_FILES_AUTHOR));
        USER_ROLES.add(new SimpleGrantedAuthority(SecurityConfiguration.ROLE_FORMS_AUTHOR));
        USER_ROLES.add(new SimpleGrantedAuthority(SecurityConfiguration.ROLE_TEMPLATES_AUTHOR));
    }

    @Override
    public boolean matches(HttpServletRequest request) {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        return "POST".equals(request.getMethod()) && auth.getAuthorities().stream().anyMatch(USER_ROLES::contains);
    }

}

因此,我正在检查Authentication是否具有我的任何用户角色,因为我的基本身份验证仅应用于我的技术用户。