Spring Boot 2 + Sping Security OAuth2是否仍支持@AuthorizationServer
注释?从阅读发行说明中可以看到一些未被移植的东西:
以下是我build.grade
的相关部分:
验证服务器
// security
compile "org.springframework.boot:spring-boot-starter-security:${springBootVersion}"
// oauth
// https://mvnrepository.com/artifact/org.springframework.security.oauth/spring-security-oauth2
compile "org.springframework.security.oauth:spring-security-oauth2:2.2.1.RELEASE"
客户端服务器
// support for Oauth2 user token services not yet migrated into Spring Boot 2.0
compile "org.springframework.security.oauth.boot:spring-security-oauth2-autoconfigure:2.0.1.BUILD-SNAPSHOT"
现在,当我尝试将Basic Authentication
中的客户端ID和客户端密码传递给/oauth/token
时,我的授权服务器Oauth2端点只返回401。传入用户名和密码会产生不同的代码路径。所以看起来OAuth过滤器并没有排成一行。
我也发现了这一点:Spring Boot 2 OAuth2 starter changes。
是否有配置更新或我是否需要一组不同的gradle依赖项才能将授权服务器恢复到之前的状态?
谢谢!
更新
我想关闭这个问题的循环。除了加密客户端机密。从Spring OAuth 2.3.2开始,RedisTokenStore问题也得到了解决:Spring OAuth 2.3.2
答案 0 :(得分:8)
Spring Security 5使用现代化的密码存储,请参阅OAuth2 Autoconfig:
如果您使用自己的授权服务器配置通过
ClientDetailsServiceConfigurer
实例配置有效客户端列表,如下所示,请注意您在此配置的密码受Spring附带的现代化密码存储的约束。安全5.
要解决您的问题,请参阅Spring Security Reference:
<强>疑难解答强>
如“密码存储格式”一节中所述,当存储的其中一个密码没有id时,会发生以下错误。
java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null" at org.springframework.security.crypto.password.DelegatingPasswordEncoder$UnmappedIdPasswordEncoder.matches(DelegatingPasswordEncoder.java:233) at org.springframework.security.crypto.password.DelegatingPasswordEncoder.matches(DelegatingPasswordEncoder.java:196)
解决错误的最简单方法是切换为明确提供密码编码的
PasswordEncoder
。解决问题的最简单方法是弄清楚当前如何存储密码并明确提供正确的PasswordEncoder
。如果要从Spring Security 4.2.x迁移,则可以通过公开NoOpPasswordEncoder
bean来恢复到先前的行为。例如,如果您使用的是Java配置,则可以创建如下所示的配置:恢复为
NoOpPasswordEncoder
并不被视为安全。您应该迁移到使用DelegatingPasswordEncoder
来支持安全密码编码。@Bean public static NoOpPasswordEncoder passwordEncoder() { return NoOpPasswordEncoder.getInstance(); }
如果您使用的是XML配置,则可以公开标识为
PasswordEncoder
的{{1}}:passwordEncoder
或者,您可以使用正确的ID为所有密码添加前缀,并继续使用
<b:bean id="passwordEncoder" class="org.springframework.security.crypto.NoOpPasswordEncoder" factory-method="getInstance"/>
。例如,如果您使用的是BCrypt,则可以通过以下方式迁移密码:DelegatingPasswordEncoder
到
$2a$10$dXJ3SW6G7P50lGmMkkmwe.20cQQubK3.HZWzG3YB1tlRy.fqvM/BG
答案 1 :(得分:5)
OAuth2 AuthorizationServer使用基本身份验证。
因此,您还需要使用AuthorizationServerConfig中的delegatedPasswordEncoder对客户端密码进行编码,以完全解决&#34;没有为id&#34; null&#34;映射的PasswordEncoder; &#34;例外。
刘瑶的回答解决了我的问题。1-创建了一个bean来自动连接PasswordEncoder;
@Bean
public PasswordEncoder passwordEncoder() {
String idForEncode = "bcrypt";
Map<String, PasswordEncoder> encoderMap = new HashMap<>();
encoderMap.put(idForEncode, new BCryptPasswordEncoder());
return new DelegatingPasswordEncoder(idForEncode, encoderMap);
}
2- AuthorizationServerConfig类中的自动有线passwordEncoder;
@Autowired
private PasswordEncoder passwordEncoder;
带有passwordEncoder的3编码CLIENT_SECRET。
@Override
public void configure(ClientDetailsServiceConfigurer configurer) throws Exception {
configurer
.inMemory()
.withClient(CLIENT_ID)
.secret(passwordEncoder.encode(CLIENT_SECRET))
.authorizedGrantTypes(GRANT_TYPE_FOR_LOGIN, GRANT_TYPE_FOR_REFRESH)
.scopes(SCOPE_READ, SCOPE_WRITE)
.accessTokenValiditySeconds(TOKEN_VALIDITY_SECONDS)
.refreshTokenValiditySeconds(TOKEN_VALIDITY_SECONDS)
.resourceIds(RESOURCES_IDS);
}
那就是它。
答案 2 :(得分:1)
如上所述@false_memories,使用Spring Boot 2,你需要编码你的秘密。在我的项目中,它看起来像:
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
String secretEncoded = passwordEncoder().encode("secret");
clients.inMemory().withClient("some-web-app").secret(secretEncoded).accessTokenValiditySeconds(expiration)
.scopes("read", "write").authorizedGrantTypes("password", "refresh_token").resourceIds("resource");
}
答案 3 :(得分:0)
我想关闭这个问题的循环。除了加密客户端机密。从Spring OAuth 2.3.2开始,RedisTokenStore
问题也得到了解决:Spring OAuth 2.3.2