版权声明:由于本人水平有限,如有错误,不吝赐教。转载请注明出处 https://blog.csdn.net/qq_41001945/article/details/86348886
一、新建类MyAuthenticationProvider继承DaoAuthenticationProvider
package com.springsecurity.handler;
import com.springsecurity.service.MyUserDetailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.PasswordEncoder;
;
import java.util.Collection;
public class MyAuthenticationProvider extends DaoAuthenticationProvider {
@Qualifier("bCryptPasswordEncoder")
@Autowired
private PasswordEncoder passwordEncoder;
private UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken;
/**
* 自定义验证方式
*/
@Override
public Authentication authenticate(Authentication authentication) {
String username = authentication.getName();
String password = (String) authentication.getCredentials();
//前端传过来的明文密码password);
String encode = passwordEncoder.encode(password);
//加密之后的密码encode
//调用UserDetailService的loadUserByUsername方法,来获取从数据库得到的对象信息
UserDetails user = this.getUserDetailsService().loadUserByUsername(username);
if(user==null){
System.out.println("用户不存在");
return authentication;
}
//加密过程在这里体现
System.out.println("结果CustomUserDetailsService后,已经查询出来的数据库存储密码:" + user.getPassword());
//判断前端传过来的密码与从数据库得到的是否一致。
if (!passwordEncoder.matches(password,user.getPassword())) {
System.out.println("密码错误!!!");
return authentication;
}
//封装用户的权限,将其封装成如下类型的集合
Collection<? extends GrantedAuthority> authorities = user.getAuthorities();
//重新封装UsernamePasswordAuthenticationToken对象,并将其返回。
usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(username, authentication.getCredentials(), authorities);
usernamePasswordAuthenticationToken.setDetails(user);
return usernamePasswordAuthenticationToken;
}
@Override
public boolean supports(Class<?> arg0) {
return true;
}
}
二、将其加入到容器中
以前我用的1.5.18版本的boot直接在MyAuthenticationProvider中注入UserDetailService.来实现自己验证处理
这个项目用的2.1.1.RELEASE这个版本,使用上述方法,则会出异常。提示得使用Setter方法来注入UserDetailService
@Bean("myAuthenticationProvider")
public AuthenticationProvider getMyAuthenticationProvider(){
MyAuthenticationProvider myAuthenticationProvider = new MyAuthenticationProvider();
myAuthenticationProvider.setUserDetailsService(myUserDetailService);
return myAuthenticationProvider;
}
三、重写方法
// 重写方法,自定义用户
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(myAuthenticationProvider);
}
完整的SpeingSecurityConfig.java代码
package com.springsecurity.config;
import com.springsecurity.handler.MyAuthenticationFailHandler;
import com.springsecurity.handler.MyAuthenticationProvider;
import com.springsecurity.handler.MyAuthenticationSuccessHandler;
import com.springsecurity.service.MyUserDetailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
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.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
@Configuration
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private MyUserDetailService myUserDetailService;
@Qualifier("myAuthenticationProvider")
@Autowired
private AuthenticationProvider myAuthenticationProvider;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/","/login.html","/testlogin","/mylogin") // 不需要登录就可以访问
.permitAll()
.antMatchers("/user/**").hasAnyRole("USER") // 需要具有ROLE_USER角色才能访问
.antMatchers("/admin/**").hasAnyRole("ADMIN") // 需要具有ROLE_ADMIN角色才能访问
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/testlogin") // 设置登录页面
.loginProcessingUrl("/mylogin")
.defaultSuccessUrl("/index") // 设置默认登录成功后跳转的页面
.and()
.csrf().disable()// 禁用跨站攻击 关闭csrf 防止循环定向
;
}
// 密码加密方式
@Bean("bCryptPasswordEncoder")
public PasswordEncoder bCryptPasswordEncoder(){
return new BCryptPasswordEncoder();
}
// 重写方法,自定义用户
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(myAuthenticationProvider);
}
@Bean("myAuthenticationProvider")
public AuthenticationProvider getMyAuthenticationProvider(){
MyAuthenticationProvider myAuthenticationProvider = new MyAuthenticationProvider();
myAuthenticationProvider.setUserDetailsService(myUserDetailService);
return myAuthenticationProvider;
}
}
测试方法如上个项目。