Spring Security

在未做其他配置时,启动时会在 console 中生成一个临时密码,使用 user/临时密码 登陆。

1. 基本配置信息

@Configuration
@EnableWebSecurity
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception{
        http.cors().and() //启用 CORS 
            .csrf().disable() //禁用 CSRF

            //设置 SESSION 状态为 STATELESS,关闭 SESSION 功能,用于 JWT 认证。
            //正常认证需删除此配置
            .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()

            .authorizeRequests()
                .antMatchers("/auth").permitAll()
                .antMatchers("/register").permitAll()
                .antMatchers("/admin").hasAuthority("ADMIN")
                .anyRequest().authenticated() //其他请求,必须属于认证的用户才可以。
                .and()
            .formLogin()
                .and()
             .logout()
                .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                .invalidateHttpSession(true)
                .logoutUrl("/logout")
                .logoutSuccessUrl("/");
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

2. JPA 数据库用户认证的实现

(2.1). 实现 UserDetails 接口

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

public class AuthUser implements UserDetails {
    private final String id;
    private final String username;
    private final String password;
    private final String email;
    private final Collection<? extends GrantedAuthority> authorities;

    public AuthUser(String id, String username, String password, String email, Collection<? extends GrantedAuthority> authorities) {
        this.id = id;
        this.username = username;
        this.password = password;
        this.email = email;
        this.authorities = authorities;
    }

    //......
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

(2.2). 创建 AuthUserFactory, 用于将 JPA User 转换为 AuthUser

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;

public class AuthUserFactory {
    private AuthUserFactory(){
    }

    public static AuthUser create(User user){
        return new AuthUser(String.valueOf(user.getId()),
                user.getName(),
                user.getPassword(),
                user.getEmail(),
                mapToGrantedAuthorities(Arrays.asList(user.getRole())));
    }

    private static List<GrantedAuthority> mapToGrantedAuthorities(List<String> authorities){
        return authorities.stream().map(SimpleGrantedAuthority::new).collect(Collectors.toList());
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

(2.3). 实现 UserDetailsService 服务接口,Web Security 由此加载认证用户

import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;

@Service
public class AuthUserDetailsService implements UserDetailsService {
    private static final Logger logger = LoggerFactory.getLogger(AuthUserDetailsService.class);

    @Autowired
    private UserRepository userRepository;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.findByName(username);

        if (user == null){
            throw new UsernameNotFoundException("No user found with " + username);
        } else {
            return AuthUserFactory.create(user);
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

(2.4). 配置 AuthUserDetailsService 到 WebSecurity

@Configuration
@EnableWebSecurity
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {
    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    public void configAuthentication(AuthenticationManagerBuilder auth) throws Exception{
        auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
    }

    @Bean
    public BCryptPasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
最近更新: 10/10/2018, 10:34:10 PM