Jim*_*mmy 37 java spring spring-security spring-boot spring-security-oauth2
我正在从Spring Boot 1.4.9迁移到Spring Boot 2.0以及Spring Security 5,我正在尝试通过OAuth 2进行身份验证.但是我收到此错误:
java.lang.IllegalArgumentException:没有为id"null"映射PasswordEncoder
从Spring Security 5的文档中,我了解到密码的存储格式已更改.
在我当前的代码中,我创建了我的密码编码器bean:
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
Run Code Online (Sandbox Code Playgroud)
但它给了我以下错误:
编码密码看起来不像BCrypt
所以我按照Spring Security 5文档更新编码器:
@Bean
public PasswordEncoder passwordEncoder() {
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
Run Code Online (Sandbox Code Playgroud)
现在如果我可以在数据库中看到密码,那么它就是存储的
{bcrypt}$2a$10$LoV/3z36G86x6Gn101aekuz3q9d7yfBp3jFn7dzNN/AL5630FyUQ
Run Code Online (Sandbox Code Playgroud)
随着第一个错误消失,现在当我尝试进行身份验证时,我收到以下错误:
java.lang.IllegalArgumentException:没有为id"null"映射PasswordEncoder
为了解决这个问题,我尝试了Stackoverflow的以下所有问题:
这是一个类似于我的问题,但没有回答:
注意:我已将加密密码存储在数据库中,因此无需再次编码UserDetailsService.
在Spring security 5文档中,他们建议您可以使用以下方法处理此异常:
DelegatingPasswordEncoder.setDefaultPasswordEncoderForMatches(的PasswordEncoder)
如果这是修复,那么我应该把它放在哪里?我试过把它放在PasswordEncoder像下面这样的bean中,但它没有用:
DelegatingPasswordEncoder def = new DelegatingPasswordEncoder(idForEncode, encoders);
def.setDefaultPasswordEncoderForMatches(passwordEncoder);
Run Code Online (Sandbox Code Playgroud)
MyWebSecurity类
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Bean
public PasswordEncoder passwordEncoder() {
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers(HttpMethod.OPTIONS)
.antMatchers("/api/user/add");
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
Run Code Online (Sandbox Code Playgroud)
MyOauth2配置
@Configuration
@EnableAuthorizationServer
protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
@Bean
public TokenStore tokenStore() {
return new InMemoryTokenStore();
}
@Autowired
@Qualifier("authenticationManagerBean")
private AuthenticationManager authenticationManager;
@Bean
public TokenEnhancer tokenEnhancer() {
return new CustomTokenEnhancer();
}
@Bean
public DefaultAccessTokenConverter accessTokenConverter() {
return new DefaultAccessTokenConverter();
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints)
throws Exception {
endpoints
.tokenStore(tokenStore())
.tokenEnhancer(tokenEnhancer())
.accessTokenConverter(accessTokenConverter())
.authenticationManager(authenticationManager);
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients
.inMemory()
.withClient("test")
.scopes("read", "write")
.authorities(Roles.ADMIN.name(), Roles.USER.name())
.authorizedGrantTypes("password", "refresh_token")
.secret("secret")
.accessTokenValiditySeconds(1800);
}
}
Run Code Online (Sandbox Code Playgroud)
请指导我这个问题.我花了好几个小时来解决这个问题,但无法修复.
Edw*_*dez 55
在配置时ClientDetailsServiceConfigurer,您还必须将新密码存储格式应用于客户端密钥.
.secret("{noop}secret")
Run Code Online (Sandbox Code Playgroud)
Sai*_*oni 39
添加.password("{noop}password")到安全配置文件。
例如 :
auth.inMemoryAuthentication()
.withUser("admin").roles("ADMIN").password("{noop}password");
Run Code Online (Sandbox Code Playgroud)
对于任何面临同样问题并且不需要安全解决方案的人 - 主要用于测试和调试 - 在内存中仍然可以配置用户.
这只是为了玩游戏 - 没有现实世界的场景.
以下使用的方法已弃用.
这是我得到它的地方:
在您WebSecurityConfigurerAdapter添加以下内容:
@SuppressWarnings("deprecation")
@Bean
public static NoOpPasswordEncoder passwordEncoder() {
return (NoOpPasswordEncoder) NoOpPasswordEncoder.getInstance();
}
Run Code Online (Sandbox Code Playgroud)
显然,密码是经过哈希处理的,但仍可在内存中使用.
当然,您也可以使用真正的PasswordEncoder类似BCryptPasswordEncoder密码并使用正确的id作为前缀:
// Create an encoder with strength 16
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(16);
String result = encoder.encode("myPassword");
assertTrue(encoder.matches("myPassword", result));
Run Code Online (Sandbox Code Playgroud)
小智 5
不知道这是否会对任何人有帮助。我的工作 WebSecurityConfigurer 和 OAuth2Config 代码如下:
OAuth2配置文件:
package com.crown.AuthenticationServer.security;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
@Configuration
public class OAuth2Config extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private UserDetailsService userDetailsService;
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("crown")
.secret("{noop}thisissecret")
.authorizedGrantTypes("refresh_token", "password", "client_credentials")
.scopes("webclient", "mobileclient");
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints
.authenticationManager(authenticationManager)
.userDetailsService(userDetailsService);
}
}
Run Code Online (Sandbox Code Playgroud)
网络安全配置器:
package com.crown.AuthenticationServer.security;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
@Configuration
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
@Override
public UserDetailsService userDetailsService() {
PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
final User.UserBuilder userBuilder = User.builder().passwordEncoder(encoder::encode);
UserDetails user = userBuilder
.username("john.carnell")
.password("password")
.roles("USER")
.build();
UserDetails admin = userBuilder
.username("william.woodward")
.password("password")
.roles("USER","ADMIN")
.build();
return new InMemoryUserDetailsManager(user, admin);
}
}
Run Code Online (Sandbox Code Playgroud)
这是该项目的链接: springboot-authorization-server-oauth2
您可以在 Spring Security 官方文档中阅读,DelegatingPasswordEncoder密码的一般格式为:{id}encodedPassword
这样 id 是用于查找应使用哪个 PasswordEncoder 的标识符,encodedPassword 是所选 PasswordEncoder 的原始编码密码。id 必须位于密码的开头,以 { 开头并以 } 结尾。如果找不到 id,则 id 将为 null。例如,以下可能是使用不同 id 编码的密码列表。所有的原始密码都是“password”。
ID 示例为:
{ bcrypt }$2a$10$dXJ3SW6G7P50lGmMkkmwe.20cQQubK3.HZWzG3YB1tlRy.fqvM/BG {noop}password { pbkdf2 }5d923b44a6d129f3ddf3e3c8d29412723dcbde72445e8ef6bf3b508fbf17fa4ed4d6b99ca763d8dc { scrypt }$e0801$8bWJaSu2IKSn9Z9kM+TPXfOc/9bdYSrN1oD9qfVThWEwdRTnO7re7Ei+fUZRJ68k9lTyuTeUp4of4g24hHnazw==$OAOec05+bXxvuu/1qZ6NUR+xQYvYv7BeL1QxwRpY5Pc=
{ sha256 }97cde38028ad898ebc02e690819fa220e88c62e0699403e94fff291cfffaf8410849f27605abcbc0
从 Spring Security 4 升级到 5 时会出现该java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"错误消息。请参阅这篇Baeldung 文章以获取完整的说明和可能的解决方案。
| 归档时间: |
|
| 查看次数: |
40587 次 |
| 最近记录: |