ProviderContextFilter直接由OAuth2AuthorizationServerConfigurer进行配置,ProviderContextFilter的唯一非空构造参数是ProviderSettings。
在OAuth中授权的提供方就是Provider,它的设定由Spring Authorization Server的配置总览提及的ProviderSettings负责,而且ProviderContextFilter的唯一非空构造参数就是它。ProviderSettings持有了一个Map,这个Map主要存储了一些OAuth2和OIDC请求端点路径。
除了issuer外,默认情况下这些属性都有默认值,参见其构建类Builder的初始化方法:
当ProviderContextFilter初始化时,优先从SharedObjects中获取ProviderSettings,如果没有的话则从Spring IoC容器中获取。
ProviderSettings是ProviderContextFilter唯一可供自定义的属性。
ProviderContextFilter的过滤逻辑为:
它负责在整个授权服务器相关的请求中维护上下文ProviderContext
的生命周期。在OAuth2授权相关的请求被拦截了之后由ProviderContextHolder保存了基于当前请求的ProviderContext,当过滤链结束或者异常时,ProviderContextHolder会重置
。
这里的ProviderContextHolder的机制类似于SecurityContextHolder,ProviderContext也似于SecurityContext。ProviderContext保存了当前请求对应的ProviderSettings。这样经过其它授权端点的时候我们就能从很方便地拿到ProviderSettings,进而取得授权Provider的相关配置信息,这就是ProviderContextFilter的作用
。
一般JWT不太需要令牌自省,它属于透明令牌;不透明令牌必须依赖令牌自省来验证解析令牌。
OAuth2TokenIntrospectionEndpointFilter同样直接由OAuth2AuthorizationServerConfigurer进行配置,负责令牌自省,在OAuth2中这个功能是提供给Resource Server做令牌校验用的。对于Resource Server来说令牌自省不是一个必须的功能。今天我们来简单研究一下这个过滤器。
这里除了自省端点通过ProviderSettings.Builder.tokenIntrospectionEndpoint间接自定义外,目前没有提供可供自定义的配置项。不过我们可以通过这个接口认识一下令牌自省的逻辑。
OAuth2TokenIntrospectionEndpointFilter配置于FilterSecurityInterceptor之后。
OAuth2令牌自省的RFC为RFC7662。
如果客户端使用了不透明令牌Opaque Token,就意味着令牌本身的内容和结构对客户端是不可知的,当携带该令牌访问受保护资源时,需要对令牌的有效性、授权范围等必要的有效信息进行检索以做出正确的访问决策。
自省请求流程
自省请求的细节都在上面的思维导图中,这里需要解释几个陌生的参数规则:
token_type_hint 表示令牌的类型,帮助授权服务器优化对该令牌的检索,这是一个可选项。
当请求头Authorization是Bearer类型的时候,需要携带一个客户端令牌,这个令牌区别于token。
当请求头Authorization是Basic类型的时候,携带一个编码串,规则是OAuth2客户端的client-id:client-secret进行BASE64编码。
举个请求的例子:
POST /oauth2/introspect HTTP/1.1
Host: localhost:9000
Accept: application/json
Content-Type: application/x-www-form-urlencoded
Authorization: Basic ZmVsb3JkOnNlY3JldA==
token= 这里放你的Token
上面的请求被tokenIntrospectionAuthenticationConverter转换为OAuth2TokenIntrospectionAuthenticationToken,然后交给对应的AuthenticationProvider负责认证.
NimbusJwkSetEndpointFilter这个过滤器直接由OAuth2AuthorizationServerConfigurer进行配置,负责处理JWKSet(请回顾前面JOSE相关的文章)端点的逻辑。这个应该是Spring Authorization Server目前最简单的过滤器,底层依赖nimbus-jose类库,顾名思义。
该过滤器构造方法需要两个参数JWKSource和JWKSet端点URI路径jwkSetEndpointUri。
其实NimbusJwkSetEndpointFilter还有一个成员属性JWKSelector,不过该属性并没有开放定义。它作用是根据条件检索JWK。
JWKSource 参见前面JWK源配置的文章。
jwkSetEndpointUri
默认值为/oauth2/jwks,为GET请求。由ProviderSettings的settings.provider.jwk-set-endpoint属性决定,参见其getJwkSetEndpoint()方法。
这个端点一般是资源服务器用的,用来初始化JwtDecoder实例,解码JWT字符串,。
处理逻辑非常简单,当请求匹配后,就从当前的JWKSource检索出JWKSet,并把公钥转换为JWK规范的JSON返回。
JWK对外只提供公钥,私钥应该避免泄露。
OAuth2AuthorizationServerMetadataEndpointFilter是一个对外提供授权服务器元信息的端点,遵循RFC8414相关的规范。由于这个过滤器也非常简单,几乎没有什么可多说的,所以本文着重结合代码讲一下RFC8414规范。
该规范的目的是提供一个开放端点方便OAuth2客户端获取授权服务器的一些配置信息、支持信息,以达到自动配置Provider的目的。该规范要求提供一个路径为/.well-known/*的URI,后缀推荐oauth-authorization-server,并支持GET请求。
当OAuth2客户端的向授权服务器发起该请求:
GET /.well-known/oauth-authorization-server HTTP/1.1
Accept: application/json
Host: localhost:9000
授权服务器收到该请求后,会把授权服务器元数据对象OAuth2AuthorizationServerMetadata以JSON的形式返回给OAuth2客户端,前面已经有相关文章展示该示例这里不再展示。