Нужно ли размещать токен OAuth2 в заголовке запроса?

Java

Должен ли Token быть помещен в заголовок запроса? Ответ определенно нет В этой статье мы поделимся процессом синтаксического анализа Spring Security oauth2 и сценариями применения его точек расширения с точки зрения исходного кода.

Описание процесса парсинга токена

Когда мы используем Spring Security oauth2, как правило, нам нужно поместить токен, применяемый центром аутентификации, в заголовок запроса для запроса целевого интерфейса, как показано на следующем рисунке ①.

Spring security oauth2 получает этот токен через перехватчик, чтобы завершить преобразование токена в информацию о текущем пользователе (UserDetails).

  • OAuth2AuthenticationProcessingFilter.doFilter
public class OAuth2AuthenticationProcessingFilter{
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException,
            ServletException {
        try {
            // 1. 根据用户请求解析令牌,组装预登陆对象
            Authentication authentication = tokenExtractor.extract(request);
            if (authentication == null) {
                // 若是预登陆状态为空,把无状态登录清空
                if (stateless && isAuthenticated()) {
                    SecurityContextHolder.clearContext();
                }
            }
            else {
                // 2. 根据token 来做真正的认证登录 Provier
                Authentication authResult = authenticationManager.authenticate(authentication);

                // 3. 登录成功逻辑
                eventPublisher.publishAuthenticationSuccess(authResult);
                SecurityContextHolder.getContext().setAuthentication(authResult);
            }
        }
        catch (OAuth2Exception failed) {
            // 异常通知逻辑  Spring Event
            ...
            return;
        }
        chain.doFilter(request, response);
    }
}

Мы в основном фокусируемся на первом шагеРазберите токен в соответствии с запросом пользователя и соберите объект перед входом в систему

посмотрите на реализацию по умолчаниюBearerTokenExtractor

public class BearerTokenExtractor implements TokenExtractor {
    @Override
    public Authentication extract(HttpServletRequest request) {
        // 1. 解析token
        String tokenValue = extractToken(request);
        if (tokenValue != null) {
            // 2. 创建一个authentication 返回
            PreAuthenticatedAuthenticationToken authentication = new PreAuthenticatedAuthenticationToken(tokenValue, "");
            return authentication;
        }
        return null;
    }

    protected String extractToken(HttpServletRequest request) {
        // 1.1 优先从请求header 获取token
        String token = extractHeaderToken(request);
        // 1.2 若是请求token 中没有,则获取请求参数中的 access_token 参数
        if (token == null) {
            token = request.getParameter(OAuth2AccessToken.ACCESS_TOKEN);
        }
        return token;
    }
}

точка расширения

    1. Расширенные каналы получения токенов и персонализированная обработка, например Nuggets.X-Legacy-Tokenне обязательноAuthorization

    1. Параметр access_token, передаваемый в параметре запроса, также может быть правильно проанализирован и обработан.

    1. переписатьBearerTokenExtractorРешить проблему, заключающуюся в том, что если запрос содержит токен, независимо от того, установлено ли для интерфейса разрешениеAll или нет, он будет перехвачен и оценен.

Приведенная выше ссылка на исходный код:Частичное расширение PigBearerTokenExtractor, системы управления разрешениями RBAC на основе Spring Boot 2.3.0, Spring Cloud Hoxton & Alibaba и OAuth2.

image