spring security oauth2.x迁移到spring security5.x 资源服务器启用url参数传递token

现象

opaque token模式使用url参数access_token传递token访问资源服务器时报错401未授权

原因

spring security 5.x默认的bear token解析器没有启用从请求参数中获取token

解决

在资源服务器安全配置中自行配置bearerTokenResolver,启用从请求参数中获取token

protected void configure(HttpSecurity http) throws Exception {
	DefaultBearerTokenResolver bearerTokenResolver = new DefaultBearerTokenResolver();
	bearerTokenResolver.setAllowUriQueryParameter(true);
	bearerTokenResolver.setAllowFormEncodedBodyParameter(true);
	http.oauth2ResourceServer()
		.bearerTokenResolver(bearerTokenResolver)
	    .opaqueToken(Customizer.withDefaults())
}

源码

  • 资源服务器配置器
    org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer
// 安全配置
@Override
public void configure(H http) {
	// 配置token解析器
	BearerTokenResolver bearerTokenResolver = getBearerTokenResolver();
	this.requestMatcher.setBearerTokenResolver(bearerTokenResolver);
	...
}
// 解析器配置接口
public OAuth2ResourceServerConfigurer<H> bearerTokenResolver(BearerTokenResolver bearerTokenResolver) {
	Assert.notNull(bearerTokenResolver, "bearerTokenResolver cannot be null");
	this.bearerTokenResolver = bearerTokenResolver;
	return this;
}
// 获取解析器
BearerTokenResolver getBearerTokenResolver() {
	if (this.bearerTokenResolver == null) {
		// 如果没有通过接口配置解析器则从上下文中获取解析器bean
		if (this.context.getBeanNamesForType(BearerTokenResolver.class).length > 0) {
			this.bearerTokenResolver = this.context.getBean(BearerTokenResolver.class);
		}
		else { // 如果上下文没有注册解析器bean,则创建默认解析器
			this.bearerTokenResolver = new DefaultBearerTokenResolver();
		}
	}
	return this.bearerTokenResolver;
}
  • 默认token解析器
    org.springframework.security.oauth2.server.resource.web.DefaultBearerTokenResolver
// 默认关闭表单参数(用于POST请求)
private boolean allowFormEncodedBodyParameter = false;
// 默认关闭url参数(用于GET请求)
private boolean allowUriQueryParameter = false;
// 解析请求中的token
public String resolve(HttpServletRequest request) {
	// 解析header
	String authorizationHeaderToken = resolveFromAuthorizationHeader(request);
	// 解析请求参数
	String parameterToken = resolveFromRequestParameters(request);
	if (authorizationHeaderToken != null) {
		if (parameterToken != null) {
			BearerTokenError error = BearerTokenErrors
					.invalidRequest("Found multiple bearer tokens in the request");
			throw new OAuth2AuthenticationException(error);
		}
		return authorizationHeaderToken;
	}
	if (parameterToken != null && isParameterTokenSupportedForRequest(request)) {
		return parameterToken;
	}
	return null;
}
// 判断是否允许从表单/url参数中传递token
private boolean isParameterTokenSupportedForRequest(HttpServletRequest request) {
	return ((this.allowFormEncodedBodyParameter && "POST".equals(request.getMethod()))
			|| (this.allowUriQueryParameter && "GET".equals(request.getMethod())));
}

posted on   路过君  阅读(107)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
历史上的今天:
2020-04-11 spring 启动时自动运行
2020-04-11 spring cloud oauth2授权服务 默认tokenService配置源码
2020-04-11 spring cloud 搭建oauth2授权服务 使用redis存储令牌
2020-04-11 spring cloud oauth2授权服务 clientDetails配置源码
2020-04-11 spring 验证框架
2020-04-11 IDEA 插件整理
2020-04-11 spring security笔记 默认登陆页面源码

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示