Должен ли 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;
}
}
точка расширения
-
- Расширенные каналы получения токенов и персонализированная обработка, например Nuggets.X-Legacy-Tokenне обязательноAuthorization
-
- Параметр access_token, передаваемый в параметре запроса, также может быть правильно проанализирован и обработан.
-
- переписатьBearerTokenExtractorРешить проблему, заключающуюся в том, что если запрос содержит токен, независимо от того, установлено ли для интерфейса разрешениеAll или нет, он будет перехвачен и оценен.
- переписатьBearerTokenExtractorРешить проблему, заключающуюся в том, что если запрос содержит токен, независимо от того, установлено ли для интерфейса разрешениеAll или нет, он будет перехвачен и оценен.
Приведенная выше ссылка на исходный код:Частичное расширение PigBearerTokenExtractor, системы управления разрешениями RBAC на основе Spring Boot 2.3.0, Spring Cloud Hoxton & Alibaba и OAuth2.