有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java何时在Spring boot应用程序中清除SecurityContext?即使在api调用完成后,它也会被保留

在我的应用程序中,我们需要验证在授权头中传递的身份验证令牌。标题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();
        }
    }
}```

共 (1) 个答案

  1. # 1 楼答案

    我猜这种行为通常与会话管理有关

    因为您使用的是基于令牌的安全性,所以需要在WebSecurityConfig中明确地将会话管理定义为无状态

    http
    .sessionManagement()
    .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
    

    有关详细信息,请参阅this