Spring security 使用CSRF令牌和BasicAuth保护同一端点的Spring Boot
我有一个Spring Boot REST应用程序,它有两个主要部分:Spring security 使用CSRF令牌和BasicAuth保护同一端点的Spring Boot,spring-security,Spring Security,我有一个Spring Boot REST应用程序,它有两个主要部分: 我想用令牌保护ajax调用的UI 我希望具有基本身份验证的公共端点 据我所知,我不能用CSRF令牌保护公共端点,因为它们需要会话。问题是,某些端点需要两者都可以访问,因此,当UI使用CSRF时,如何使用CSRF保护它们,并禁用基本身份验证的CSRF 这是我目前拥有的,我完全禁用了csrf,所以基本工作 http.requestMatchers().antMatchers("/form/fill", "/form/fill/
- 我想用令牌保护ajax调用的UI
- 我希望具有基本身份验证的公共端点
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();
编辑:我找到了旧答案,我想知道是否有一种方法可以在我的案例中利用它,但我仍然不确定如何区分“本地”用户和通过httpBasic()验证的用户在Spring Security java配置文件中,您可以如下配置
HttpSecurity
对象,以便仅在某些请求上启用CSRF
检查(默认情况下,在所有传入请求上启用,而disable将对所有传入请求禁用,因此request Mather可以在此处帮助您找到要启用或禁用的路径csrf
)
确保用csrf check/**替换/URL,并按端点或多个路径替换路径
@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();
}
有了@kj007的输入,我就可以让它工作了。
我使用的是requireCsrfProtectionMatcher
,我的matcher就是这样的:
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);
}
}
公共类UIRequestMatcher实现RequestMatcher{
public static final List USER_ROLES=new ArrayList();
静止的{
添加(新的SimpleGrantedAuthority(SecurityConfiguration.ROLE\u ADMIN));
USER_ROLES.add(新的SimpleGrantedAuthority(SecurityConfiguration.ROLE_FILES_AUTHOR));
USER_ROLES.add(新的SimpleGrantedAuthority(SecurityConfiguration.ROLE_FORMS_AUTHOR));
USER_ROLES.add(新的SimpleGrantedAuthority(SecurityConfiguration.ROLE_TEMPLATES_AUTHOR));
}
@凌驾
公共布尔匹配(HttpServletRequest){
Authentication auth=SecurityContextHolder.getContext().getAuthentication();
返回“POST”.equals(request.getMethod())&&auth.getAuthorities().stream().anyMatch(用户角色::包含);
}
}
因此,我正在检查身份验证是否具有我的任何用户角色,因为我的基本身份验证只应用于我的技术用户。对于公共URL,make.permitAll()和任何请求都应进行身份验证。@kj007可能我将其表述为错误,但“public”仍然应该使用httpBasic保护令牌,但是httpBasic和CSRF令牌不会一起工作,除非您有额外的“握手”请求来检索令牌,这将使RESTfulity无效。谢谢,我现在只需要找到一种方法来识别本地用户。我设法使用“XMLHttpRequest”检查ajax。等于(request.getHeader(“X-request-With”))但是有一些正常的表单提交。我想到的唯一一件事是一个隐藏字段并检查它的存在,但这不是很安全。你可以为http basic定义角色??如果我理解正确,我可以检查用户角色,但我如何仅从HttpServletRequest获取角色?Spring安全将检查Principal具有“本地”权限(您可以在ant matcher hasRole(“本地”)中使用),但我如何在requireCsrfProtectionMatcher中组合此权限,例如为此权限启用CSRF?