Skip to content

Commit

Permalink
增加passwordEncoder的合理配置
Browse files Browse the repository at this point in the history
  • Loading branch information
lexburner committed Apr 23, 2018
1 parent ec9fc3d commit b997bb9
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 9 deletions.
41 changes: 39 additions & 2 deletions README.md
Expand Up @@ -21,18 +21,55 @@ https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.0-Migration-Gu
## 改动二 添加PasswordEncoder

如果你得到这个异常

java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"
springboot2.0 需要增加一个加密器,原来的 plainTextPasswordEncoder 新版本被移除


### 方法一
```
@Bean
PasswordEncoder passwordEncoder(){
return NoOpPasswordEncoder.getInstance();
}
```
springboot2.0 需要增加一个加密器,原来的 plainTextPasswordEncoder 新版本被移除

如上是最简单的修改方式,但缺点很明显,是使用明文存储的密码

### 方法二

```
@Bean
PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
String finalPassword = new BCryptPasswordEncoder().encode("123456");
String finalSecret = new BCryptPasswordEncoder().encode("123456");
```

配置具体的 BCryptPasswordEncoder,别忘了存储的密码和oauth client 的 secret 也要存储对应的编码过后的密码,而不是明文!

### 方法三

```
@Bean
PasswordEncoder passwordEncoder(){
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
String finalPassword = "{bcrypt}"+new BCryptPasswordEncoder().encode("123456");
String finalSecret = "{bcrypt}"+new BCryptPasswordEncoder().encode("123456");
```

使用 PasswordEncoderFactories.createDelegatingPasswordEncoder() 创建一个 DelegatingPasswordEncoder,这个委托者通过密码的前缀来
区分应该使用哪一种编码器去校验用户登录时的密码,文档中推荐使用这种方式,并且推荐使用 Bcrypt 而不是 md5,sha256 之类的算法,具体原因看文档

了解细节戳这里:https://docs.spring.io/spring-security/site/docs/5.0.4.RELEASE/reference/htmlsingle/#10.3.2 DelegatingPasswordEncoder




## 改动三 注意Redis的版本

如果你在使用新版本的oauth2时发现有redis的相关报错,如redis-client找不到相应的接口,序列化问题时,请注意下 spring-security-oauth2 的版本
Expand Down
Expand Up @@ -8,6 +8,7 @@
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
Expand Down Expand Up @@ -59,19 +60,26 @@ protected static class AuthorizationServerConfiguration extends AuthorizationSer

@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {

// password 方案一:明文存储,用于测试,不能用于生产
// String finalSecret = "123456";
// password 方案二:用 BCrypt 对密码编码
// String finalSecret = new BCryptPasswordEncoder().encode("123456");
// password 方案三:支持多种编码,通过密码的前缀区分编码方式
String finalSecret = "{bcrypt}"+new BCryptPasswordEncoder().encode("123456");
//配置两个客户端,一个用于password认证一个用于client认证
clients.inMemory().withClient("client_1")
.resourceIds(DEMO_RESOURCE_ID)
.authorizedGrantTypes("client_credentials", "refresh_token")
.scopes("select")
.authorities("oauth2")
.secret("123456")
.secret(finalSecret)
.and().withClient("client_2")
.resourceIds(DEMO_RESOURCE_ID)
.authorizedGrantTypes("password", "refresh_token")
.scopes("select")
.authorities("oauth2")
.secret("123456");
.secret(finalSecret);
}

@Override
Expand Down
Expand Up @@ -5,12 +5,13 @@
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
Expand All @@ -26,16 +27,23 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

// @Override
// protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// auth.inMemoryAuthentication().passwordEncoder(NoOpPasswordEncoder.getInstance());
// auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder());
// }


@Bean
@Override
protected UserDetailsService userDetailsService(){
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
// password 方案一:明文存储,用于测试,不能用于生产
// String finalPassword = "123456";
// password 方案二:用 BCrypt 对密码编码
// String finalPassword = bCryptPasswordEncoder.encode("123456");
// password 方案三:支持多种编码,通过密码的前缀区分编码方式
String finalPassword = "{bcrypt}"+bCryptPasswordEncoder.encode("123456");
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
manager.createUser(User.withUsername("user_1").password("123456").authorities("USER").build());
manager.createUser(User.withUsername("user_2").password("123456").authorities("USER").build());
manager.createUser(User.withUsername("user_1").password(finalPassword).authorities("USER").build());
manager.createUser(User.withUsername("user_2").password(finalPassword).authorities("USER").build());
return manager;
}

Expand All @@ -44,9 +52,24 @@ protected UserDetailsService userDetailsService(){
* https://docs.spring.io/spring-security/site/docs/5.0.4.RELEASE/reference/htmlsingle/#10.3.2 DelegatingPasswordEncoder
*
*/


// password 方案一:明文存储,用于测试,不能用于生产
// @Bean
// PasswordEncoder passwordEncoder(){
// return NoOpPasswordEncoder.getInstance();
// }

// password 方案二:用 BCrypt 对密码编码
// @Bean
// PasswordEncoder passwordEncoder(){
// return new BCryptPasswordEncoder();
// }

// password 方案三:支持多种编码,通过密码的前缀区分编码方式,推荐
@Bean
PasswordEncoder passwordEncoder(){
return NoOpPasswordEncoder.getInstance();
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}

//
Expand Down

0 comments on commit b997bb9

Please sign in to comment.