实战

首先创建一个普通的 Spring Boot 工程,并引入 spring-boot-starter-security 依赖。

创建一个测试接口 /hello,代码如下:

@RestController
public class HelloController {
    @GetMapping("/hello")
    public String hello() {
        return "hello";
    }
}

为了测试方便,我们首先在单元测试中执行如下代码,生成一段加密字符串(读者可以多次执行该方法,会发现相同的明文每次生成的密文都不相同,这也是 BCryptPasswordEncoder 的便捷之处):

void contextLoads() {
    BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
    System.out.println(encoder.encode("123"));
}

接下来自定义 SecurityConfig 类:

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("javaboy")
                .password("$2a$10$XtBXprcqjT/sGPEOY5y1eurS.V.9U7/M5RD1i32k1uAhXQHK4//U6")
                .roles("admin");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .and()
                .csrf().disable();
    }
}
  1. 首先我们将一个 BCryptPasswordEncoder 实例注册到 Spring 容器中,这将代替默认的 DelegatingPasswordEncoder。

  2. 在定义用户时,设置的密码字符串就是前面单元测试方法执行生成的加密字符串。

配置完成后,启动项目。项目启动成功后,我们就可以使用 javaboy/123 进行登录了。

另一方面,由于默认使用的是 DelegatingPasswordEncoder,所以也可以不配置 PasswordEncoder 实例,只在密码前加上前缀:

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .withUser("javaboy")
                .password("{bcrypt}$2a$10$XtBXprcqjT/sGPEOY5y1eurS.V.9U7/M5RD1i32k1uAhXQHK4//U6")
                .roles("admin")
                .and()
                .withUser("江南一点雨")
                .password("{noop}123")
                .roles("user");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .and()
                .csrf().disable();
    }
}

如果我们不提供 PasswordEncoder 实例的话,默认使用的就是 DelegatingPasswordEncoder,所以需要给加密字符串加上前缀 {bcrypt},同时再添加一个新用户,新用户的密码是 {noop}123,这个表示密码明文存储,密码就是 123。

配置完成后,再次重启项目,此时我们就可以使用 javaboy/123 和 江南一点雨/123 两个用户进行登录了。