【发布时间】:2019-01-25 23:10:20
【问题描述】:
我正在学习如何将 oauth2 集成到我们的 Spring Boot 项目中,以保护我们的 API。因此,我从一个基本示例开始,该示例从运行良好的spring-security-oauth2-boot 读取,然后当我尝试修改密码编码器以使用我无法验证的任何编码器时。
这是我的 AuthorizationServerConfiguration:
@Component
@EnableResourceServer
@EnableAuthorizationServer
class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
AuthenticationManager authenticationManager
AuthorizationServerConfiguration(AuthenticationConfiguration authenticationConfiguration) throws Exception {
this.authenticationManager = authenticationConfiguration.getAuthenticationManager()
}
@Override
void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("myclient")
//.secret("{noop}password") <-- this works
.secret("{pbkdf2}5d923b44a6d129f3ddf3e3c8d29412723dcbde72445e8ef6bf3b508fbf17fa4ed4d6b99ca763d8dc")
.authorizedGrantTypes("client_credentials")
.scopes("all")
.accessTokenValiditySeconds(3600)
}
@Override
void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager)
}
}
当我使用{noop}password 时,我可以成功地使用 curl 进行身份验证:
$ curl myclient:password@localhost:8080/oauth/token?scope=all -d grant_type=client_credentials
{"access_token":"4320fa79-38c2-45b1-a788-5ea1b5ce881a","token_type":"bearer","expires_in":3599,"scope":"all"}
但是当我打开任何散列时,我无法进行身份验证。我尝试过这种方式来使用 curl 进行身份验证,但没有运气:
$ curl congero:5d923b44a6d129f3ddf3e3c8d29412723dcbde72445e8ef6bf3b508fbf17fa4ed4d6b99ca763d8dc@localhost:8080/oauth/token?scope=all -d grant_type=client_credentials
{"error":"unauthorized","error_description":"Full authentication is required to access this resource"}
$ curl congero:{pbkdf2}5d923b44a6d129f3ddf3e3c8d29412723dcbde72445e8ef6bf3b508fbf17fa4ed4d6b99ca763d8dc@localhost:8080/oauth/token?scope=all -d grant_type=client_credentials
{"error":"unauthorized","error_description":"Full authentication is required to access this resource"}
我还在代码中添加了这个 sn-p 来生成密码以进行双重检查,这给了我一个不同的散列,也用 curl 测试过,也没有运气:
PasswordEncoder passwordEncoder = new Pbkdf2PasswordEncoder()
String encoded = passwordEncoder.encode('password')
println "PASSWORD: $encoded"
$ curl congero:91d1ee4784686a2e2a39c214f5a4b3ebb41e1206e2d1fc770d3ff146b034f8c156ea279c73aa1629@localhost:8080/oauth/token?scope=all -d grant_type=client_credentials
{"error":"unauthorized","error_description":"Full authentication is required to access this resource"}
$ curl congero:{pbkdf2}91d1ee4784686a2e2a39c214f5a4b3ebb41e1206e2d1fc770d3ff146b034f8c156ea279c73aa1629@localhost:8080/oauth/token?scope=all -d grant_type=client_credentials
{"error":"unauthorized","error_description":"Full authentication is required to access this resource"}
我已经调试了 spring 源代码,发现在密码编码器(Pbkdf2PasswordEncoder 和 BcryptPasswordEncoder)中,密码正在使用这种方法进行解码:
private byte[] decode(String encodedBytes) {
if(this.encodeHashAsBase64) {
return Base64.getDecoder().decode(encodedBytes);
}
return Hex.decode(encodedBytes);
}
这个Hex.decode 看起来是不匹配密码的罪魁祸首,而使用{noop} 时不会发生这种情况。
知道我在这里做错了什么吗?我错过了任何重要的步骤吗?我不清楚该文档,因为它没有显示如何逐步自定义配置。
【问题讨论】:
-
你是怎么得到秘密
{pbkdf2}5d923b44a6d129f3ddf3e3c8d29412723dcbde72445e8ef6bf3b508fbf17fa4ed4d6b99ca763d8dc的? -
@AbdelghaniRoussi 从此处的示例中复制spring.io/blog/2017/11/01/…
-
因此您可以注册一个
Pbkdf2PasswordEncoder(仅适用于 Pbkdf2 案例)或使用DelegatingPasswordEncoder,在这两种情况下您都需要一个 PasswordEncoder bean
标签: spring spring-boot groovy oauth-2.0 spring-security-oauth2