1、实现 UserDetails
public class MyUserDetails implements UserDetails {
private String username;
private String password;
private List<GrantedAuthority> list;
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
public List<GrantedAuthority> getList() {
return list;
}
public void setList(List<GrantedAuthority> list) {
this.list = list;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return list;
}
@Override
public String getPassword() {
return password;
}
@Override
public String getUsername() {
return username;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
2、实现 UserDetailsService 查询数据(username)
@Component
public class MyUserDetailService implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
MyUserDetails userDetails = null;
//模拟查询数据库
if(username.equals("zhangsan")){
userDetails = new MyUserDetails();
userDetails.setUsername("zhangsan");
userDetails.setPassword("123");
userDetails.setList(AuthorityUtils.commaSeparatedStringToAuthorityList("admin,role_manager"));
}
return userDetails;
}
}
3、实现 AuthenticationProvider
@Component
public class MyLoginProvider implements AuthenticationProvider {
@Autowired
private MyUserDetailService myUserDetailService;
@Autowired
private PasswordEncoder passwordEncoder;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
//获取请求参数-用户名
String username = (String) authentication.getPrincipal();
// //获取请求参数-密码
String password = (String) authentication.getCredentials();
//调用自定义的查询数据库的方法
UserDetails userDetails = myUserDetailService.loadUserByUsername(username);
//判断数据库中是否存在该用户名
if(userDetails==null){
//不存在的话 抛出异常
throw new UsernameNotFoundException("UsernameNotFoundException");
}
boolean b = passwordEncoder.matches(password,passwordEncoder.encode(userDetails.getPassword()));
if(!b){
//不存在的话 抛出异常
throw new UsernameNotFoundException("PasswordException");
}
//存在就返回对应的数据
UsernamePasswordAuthenticationToken token =
new UsernamePasswordAuthenticationToken(username,password,userDetails.getAuthorities());
return token;
}
@Override
public boolean supports(Class<?> authentication) {
return true;
}
}
4、实现 AuthenticationManager
@Component
public class MyLoginManager implements AuthenticationManager {
@Autowired
private MyLoginProvider provider;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
//调用了Provider的authenticate
Authentication authentication1 = provider.authenticate(authentication);
//返回
return authentication1;
}
}
5、实现 AbstractAuthenticationProcessingFilter
public class MyLoginFilter extends AbstractAuthenticationProcessingFilter {
public MyLoginFilter(AuthenticationManager myLoginManager, AuthenticationSuccessHandler successHandler, AuthenticationFailureHandler failureHandler){
super(new AntPathRequestMatcher("/user/login","POST"));
this.setAuthenticationManager(myLoginManager);
this.setAuthenticationSuccessHandler(successHandler);
this.setAuthenticationFailureHandler(failureHandler);
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
//获取到用户名和密码
String username = request.getParameter("username");
String password = request.getParameter("password");
//封装对象,目的是调用Manager
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username,password,null);
//调用Manager的authenticate
return this.getAuthenticationManager().authenticate(token);
}
}
6、配置Security
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private MyLoginProvider provider;
@Autowired
private MyLoginManager myLoginManager;
@Autowired
private LoginFailureHandler myailureHandler;
@Autowired
private LoginSuccessHandler mySuccessHandler;
@Autowired
private MyUserDetailService myUserDetailService;
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
@Bean
public MyLoginFilter loginFilter(){
return new MyLoginFilter(myLoginManager,mySuccessHandler,myailureHandler);
}
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return myLoginManager;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(myUserDetailService).passwordEncoder(passwordEncoder());
auth.authenticationProvider(provider);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// http
// //不通过Session获取SecurityContext
// .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
// .and()
// //允许基于使用HttpServletRequest限制访问
// .authorizeRequests();
http
// .authorizeRequests()
// .antMatchers("/user/login").permitAll()
// .antMatchers("/user/regist").permitAll()
.antMatchers("/user/getUser").hasAnyRole("admin")
.antMatchers("/user/delUser").hasAnyRole("manager")
// .anyRequest().authenticated()
// .and()
.addFilterAt(loginFilter(), UsernamePasswordAuthenticationFilter.class)
.csrf().disable()
.httpBasic().disable();
}
}