在Sping Boot 中,是否可以使用OAuth2和API密钥对客户端进行身份验证?假设我有一个带有UI的应用程序。用户登录UI并从OAuth2服务器获得一个jwt令牌。安全配置如下所示
...
http.authorizeRequests()
....
.anyRequest().authenticated().and()
.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
oauth2服务器在application.yml文件中配置。
比如说,我想向其他客户端公开一些后端API,并且只通过验证API Key来授权它们。我可以在我的安全配置中添加addFilterBefore
吗?这是否意味着它将同时验证API密钥和oauth jwt?
http.addFilterBefore(new SomeApiKeyFilter(...))
....
.anyRequest().authenticated().and()
.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
这可能吗?因为当我试图调用一个端点时,它抛出一个错误,说... APIKeyAuthenticationToken cannot be cast to JwtAuthenticationToken
。
2条答案
按热度按时间kpbwa7wx1#
正如@ch4mp所说,你必须定义两个安全配置。我通过在安全配置类中添加两个内部类(作为配置)而不是创建两个Bean来做到这一点。让我给你看一个例子:
如果您尝试访问yyy基路径,则会收到表单登录信息;如果您尝试访问xxx基路径,则会收到401 http错误信息。
kx1ctssn2#
您的问题的表述方式反映了您的配置问题:一个请求不会同时被API密钥和
Bearer
访问令牌授权。它将使用一个或另一个进行授权,并且在每种情况下都应该由不同的安全过滤器链处理。因此,不要在现有链中添加过滤器,而是向Web安全配置中添加另一个
SecurityFilterChain
bean。要在一个应用程序中有多个过滤器链
@Bean
,它应该:@Order
装饰@Order
中的最后一个之外,所有的都包含一个http.securityMatcher(...)
来定义它应该处理哪些请求(@Order
中的最后一个被用作所有不匹配的请求的默认值)附1
您应该认真考虑使用OAuth2
client_credentials
流,而不是API密钥,并使用单个标准OAuth2过滤器链处理由两个authorization_code
获得的令牌)client_credentials
获取令牌)附2
您应该检查源代码中是否有
JwtAuthenticationToken
的显式引用,以及此APIKeyAuthenticationToken
来自何处(似乎不是Spring版本的一部分,至少不是最近的版本)。如果你配置了两个安全过滤器链@Bean
,并且每个都用自己的Authentication
类型填充安全上下文,那么你必须使用这种身份验证多态(或使用公共的父类/接口)来编写代码。