Kel*_*lyM 7 java spring spring-security spring-boot
这是对早期问题的后续跟进.
我正在尝试将OAuth2应用程序迁移到Spring Boot 2/Security 5.根据我之前的问题(和此)中的一条评论,似乎密码的存储格式正在发生变化.
在我原来的(Spring 1.5.9)应用程序中,我明确指定了BCrypt
// AppConfig
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
Run Code Online (Sandbox Code Playgroud)
// SecurityConfig
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userService)
.passwordEncoder(passwordEncoder);
}
Run Code Online (Sandbox Code Playgroud)
这导致错误,密码"看起来不像BCrypt(我之前的问题的原因).
感谢回复我之前的问题的评论,似乎我需要使用{bcrypt}为存储的密码添加前缀.我还用以下代码替换了我的PassowrdEncoder @Bean:
PasswordEncoder passwordEncoder =
PasswordEncoderFactories.createDelegatingPasswordEncoder();
Run Code Online (Sandbox Code Playgroud)
但是,这导致以下错误:
java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"
接下来,我尝试将更@Bean改为以下内容:
@Bean
public PasswordEncoder passwordEncoder() {
String idForEncode = "bcrypt";
Map encoders = new HashMap<>();
encoders.put(idForEncode, new BCryptPasswordEncoder());
encoders.put("pbkdf2", new Pbkdf2PasswordEncoder());
encoders.put("scrypt", new SCryptPasswordEncoder());
return new DelegatingPasswordEncoder(idForEncode, encoders);
}
Run Code Online (Sandbox Code Playgroud)
这导致了同样的错误.用户创建部分似乎按预期工作.运行以下内容:
@Bean
public CommandLineRunner demo(UserRepository repository) {
return(args) -> {
OAuthUser user = new OAuthUser();
user.setFirstName("K");
user.setLastName("M");
user.setPassword(passwordEncoder.encode("L"));
user.setUserName("KLM");
repository.save(user);
};
}
Run Code Online (Sandbox Code Playgroud)
导致用户使用密码{bcrypt}$2a$10$p/W7UV.fkghBRMzuDhh7z.G0uPLze9yFMLarbHdmwinzlqAHrMUQi.
但是,用户验证失败.发出此请求:
curl --request POST \
--url http://web:secret@localhost:8090/oauth/token \
--header 'content-type: multipart/form-data; boundary=---011000010111000001101001' \
--form grant_type=password \
--form username=KLM \
--form 'pasword =L'
Run Code Online (Sandbox Code Playgroud)
给出"消息":"没有为id \"null \""消息映射PasswordEncoder.
首先,任何有关问题可能出现的建议都将受到赞赏.
其次,关于迁移到新的存储格式,我还有另一个问题.这种存储格式,即{id]password标准或特定于Spring的东西?基本上,在过去,如果密码存储为BCrypt,我可能会从C#或其他应用程序验证密码.需要知道的所有应用程序是如何处理BCrypt标准.这种新的存储格式是否会抑制通过非Spring应用程序验证用户的能力?
谢谢.
编辑:
我最终让Spring Boot 2/Security 5与OAuth2一起工作.虽然我不记得确切的步骤(我一直在处理一些Spring项目),但我发布的是希望我的相关配置作为指导.
确保添加密码编码器bean:
@Bean
public PasswordEncoder passwordEncoder() {
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
//return new BCryptPasswordEncoder();
}
Run Code Online (Sandbox Code Playgroud)
对于授权服务器,请确保在AuthorizationServerSecurityConifgurer和ClientDetailsServiceConfigurer部分中引用它们.
@EnableAuthorizationServer
@Configuration
public class AuthConfig extends AuthorizationServerConfigurerAdapter {
// Some code omitted for brevity
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.passwordEncoder(passwordEncoder);
security.checkTokenAccess("permitAll()");
security.tokenKeyAccess("permitAll()");
}
@Override
public void configure(ClientDetailsServiceConfigurer configurer) throws Exception {
JdbcClientDetailsService details = new JdbcClientDetailsService(appConfig.dataSource());
details.setPasswordEncoder(passwordEncoder);
configurer.withClientDetails(details);
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
TokenEnhancerChain enhancerChain = new TokenEnhancerChain();
endpoints.tokenStore(tokenStore).accessTokenConverter(converter)
.userDetailsService(userService)
.authenticationManager(authenticationManager);
}
Run Code Online (Sandbox Code Playgroud)
在SecurityConfig中,确保使用AuthenticationManagerBuilder注册它.
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userService).passwordEncoder(passwordEncoder);
}
Run Code Online (Sandbox Code Playgroud)
确保配置您的ResourceServer,包括HttpSecurity端点.
EnableResourceServer
@Configuration
public class ResourceConfig extends ResourceServerConfigurerAdapter {
private AppConfig appConfig;
@Autowired
private ResourceServerTokenServices tokenService;
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
public ResourceConfig(AuthenticationManager authenticationManager, AppConfig appConfig) {
this.authenticationManager = authenticationManager;
this.appConfig = appConfig;
}
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
resources.resourceId("321");
resources.tokenServices(tokenService);
}
@Override
public void configure(HttpSecurity http) throws Exception {
http.headers().frameOptions().disable().and().requestMatchers().and().authorizeRequests()
.antMatchers("/user/**").hasAuthority("ROLE_ADMIN").antMatchers("/h2/**").permitAll();
}
Run Code Online (Sandbox Code Playgroud)
我相信这些@Config课程往往最相关.我的UserDetailsService实现没有什么特别之处,我认为我甚至没有在这个应用程序中扩展或自定义客户端(在@Config中看到的内容之外).
| 归档时间: |
|
| 查看次数: |
1417 次 |
| 最近记录: |