OAuth2 Token 必定要放在请求头中吗?

Token 必定要放在请求头中吗? 答案确定是否认的,本文将从源码的角度来分享一下 spring security oauth2 的解析过程,及其扩展点的应用场景。java

Token 解析过程说明

当咱们使用 spring security oauth2 时, 通常状况下须要把认证中心申请的 token 放在请求头中请求目标接口,以下图 ①git

spring security oauth2 经过拦截器获取此 token 完成令牌到当前用户信息(UserDetails)的转换。spring

  • 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);
	}
}

咱们主要来关注第一步 根据用户请求解析令牌,组装预登录对象less

来看默认实现 BearerTokenExtractoride

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. 丰富获取 token 渠道,个性化处理.例如掘金的 X-Legacy-Token 而非必须是 Authorization

    1. 请求参数中携带 access_token 参数也能被正确解析处理

    1. 重写 BearerTokenExtractor 解决,若请求携带 token 不管接口是否被设置 permitAll 都会被拦截判断的问题

以上源码参考: 基于 Spring Boot 2.3.0、 Spring Cloud Hoxton & Alibaba、 OAuth2 的 RBAC 权限管理系统 PigBearerTokenExtractor 部分扩展code

项目推荐: Spring Cloud 、Spring Security OAuth2的RBAC权限管理系统 欢迎关注component

相关文章
相关标签/搜索