Когда SecurityContext очищается при загрузке Spring? Он сохраняется даже после завершения вызова API - PullRequest
0 голосов
/ 03 марта 2020

В моем приложении нам нужно проверить токен аутентификации, переданный в заголовке авторизации. Оба заголовка clientName и Authorizaiton являются обязательными. Если clientName не передается, мы просто должны записать, что «имя клиента отсутствует в запросе». В конфигурации Auth мы применяем безопасность только к операциям записи. Проблема заключается в том, что если в первый раз передаются правильные clientName и токен авторизации, то следующие вызовы API работают нормально, даже если отсутствуют оба требуемых заголовка (проблема наблюдается при выполнении вызова от swagger / почтальона. Ожидаемый ответ - 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);

Вот AuthConfiguration:

@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 Ответ

0 голосов
/ 04 марта 2020

Полагаю, такое поведение обычно связано с управлением сеансами.

Поскольку вы используете безопасность на основе токенов, необходимо явно определить Session Management как Stateless в WebSecurityConfig что-то вроде этого

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

Подробнее см. this

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...