Java 何时在Spring boot应用程序中清除SecurityContext?它';即使在api调用完成后也会保留
在我的应用程序中,我们需要验证在授权头中传递的身份验证令牌。标题clientName和Authorization都必须为空。如果没有传递clientName,我们只需要记录“请求中缺少客户端名称”。在Auth配置中,我们仅对写入操作应用安全性。问题是-如果第一次传递了正确的clientName和auth令牌,那么即使缺少两个必需的头,下一次api调用也可以正常工作(从swagger/postman调用时观察到问题。预期响应-403:禁止) 然而,当我卷曲它时,我得到了正确的禁止错误代码。当我调试它时,发现Java 何时在Spring boot应用程序中清除SecurityContext?它';即使在api调用完成后也会保留,java,spring,spring-security,Java,Spring,Spring Security,在我的应用程序中,我们需要验证在授权头中传递的身份验证令牌。标题clientName和Authorization都必须为空。如果没有传递clientName,我们只需要记录“请求中缺少客户端名称”。在Auth配置中,我们仅对写入操作应用安全性。问题是-如果第一次传递了正确的clientName和auth令牌,那么即使缺少两个必需的头,下一次api调用也可以正常工作(从swagger/postman调用时观察到问题。预期响应-403:禁止) 然而,当我卷曲它时,我得到了正确的禁止错误代码。当我调试
SecurityContextHolder.getContext()
仍在返回上次设置的上下文
当缺少标头时,是否还需要执行SecurityContextHolder.getContext().setAuthentication(null)
下面是示例代码:
if (StringUtils.isEmpty(httpRequest.getHeader(clientName)) {
log.info("missing client information");
} else {
final String authorizationHeader = httpRequest.getHeader(HttpHeaders.AUTHORIZATION);
if (!StringUtils.isEmpty(clientName) && !StringUtils.isEmpty(authorizationHeader)) {
Matcher matcher = BEARER_TOKEN_PATTERN.matcher(authorizationHeader);
if (matcher.matches()) {
Client client = null;
try {
client = authService.load(clientName);
} catch (NotFoundException e) {
log.debug("Client not registered");
}
final String storedToken = !ObjectUtils.isEmpty(client) ? client.getClientSecret() : StringUtils.EMPTY;
if (storedToken.equals(matcher.group(2))) {
ClientAuthentication clientAuthentication = new ClientAuthentication(client, storedToken, client.getScopes());
SecurityContextHolder.getContext().setAuthentication(clientAuthentication);
}
}
}
}
}
chain.doFilter(request, response);
以下是AUTH配置:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
public class AuthConfiguration extends WebSecurityConfigurerAdapter {
private final Boolean isSecurityEnabled;
@Autowired
private AuthService authService;
@Autowired
public AuthConfiguration(final MyProps props) {
isSecurityEnabled = props.getIsSecurityEnabled();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.addFilterBefore(new MyCustomAuthenticationFilter(authService), BasicAuthenticationFilter.class);
if (isSecurityEnabled) {
http.requestCache()
.requestCache(new NullRequestCache())
.and().csrf().disable().formLogin().disable()
.authorizeRequests().antMatchers(HttpMethod.OPTIONS).permitAll()
.antMatchers(HttpMethod.POST, "/api/v*/channels/**")
.hasAnyAuthority(Scope.CHANNELS_WRITE.getDefaultScope(), Scope.ADMIN.getDefaultScope())
.antMatchers(HttpMethod.PUT, "/api/v*/channels/**")
.hasAnyAuthority(Scope.CHANNELS_WRITE.getDefaultScope(), Scope.ADMIN.getDefaultScope())
.antMatchers(HttpMethod.GET).permitAll()
.antMatchers(HttpMethod.PUT).authenticated()
.antMatchers(HttpMethod.DELETE).authenticated()
.antMatchers(HttpMethod.PATCH).authenticated()
.antMatchers(HttpMethod.POST).authenticated();
} else {
http.csrf().disable().formLogin().disable().authorizeRequests()
.antMatchers("/api/**").permitAll();
}
}
}```
我猜这种行为通常与会话管理有关 由于您使用的是基于令牌的安全性,因此需要在
WebSecurityConfig
中明确地将会话管理定义为无状态
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
有关更多详细信息,请参见能否添加网站安全配置详细信息我已添加了网站安全配置详细信息。非常感谢。它工作得很好。但我很好奇,为什么早些时候我使用cURL时它工作得很好,而不是通过邮递员/招摇过市。