自定义认证流程
- 创建配置类WebSecurityConfig继承WebSecurityConfigurerAdapter
- 复写configure方法去进行授权配置
- 因为要用到mapper接口需要注入所以将配置类交给spring管理
1.创建类继承Userdetail
public class MyUserDetailService implements UserDetailsService {
}
2.导包 配置yml 集成mybatis
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:mysql:///auth
username: root
password: 123456
#扫描mapper.xml
mybatis:
mapper-locations: classpath:cn/itsource/security/mapper/*Mapper.xml
#配置别名
type-aliases-package: cn.itsource.security.domain
server:
port: 80
- 实现接口UserDetailsService重写loadUserByUsername
3.然后根据用户名查询用户 需要调用mapper接口 注入mapper所以把该类交给spring管理打上@Component注解
//通过用户名查询用户
MyUser myUser = myUserMapper.loadByUsername(username);
if(myUser == null){
throw new UsernameNotFoundException("无效的用户名");
}
4.根据用户id查询权限
//通过用户id查询用户所拥有的权限
List<Permission> permissions = permissionMapper.loadByMyUserId(myUser.getId());
- 重写的loadUserByUsername方法需要返回UserDetails但是由于是个接口所以去找子类 子类有个User类 就返回一个User
- 返回的User类需要三个参数
- 而权限集合需要GrantedAuthority类型但是GrantedAuthority又是接口就去找子类 SimpleGrantedAuthority implements GrantedAuthority
所以将查询到的权限集合转换成需要的集合
//需要SimpleGrantedAuthority类型的
List<SimpleGrantedAuthority> authorities=new ArrayList<>();
//permissions 放在authorities里面permissions
permissions.forEach(permission ->
authorities.add(new SimpleGrantedAuthority(permission.getExpression())));
5.返回User
//封装成一个USerDetailService String username, String password, Collection authorities
User user=new User(myUser.getUsername(),myUser.getPassword(),authorities);
return user;
- 配置类
6.把密码密文保存
@Bean//密码编码
public PasswordEncoder passwordEncoder(){
//return NoOpPasswordEncoder.getInstance();//不加密
//加密
return new BCryptPasswordEncoder();
}
- 查询所有的权限
List<Permission> permissions = permissionMapper.loadAll();
- 把权限设置给security
//把权限设置给security
for (Permission permission : permissions) {
// 对外暴露resource资源 有满足条件的resource才可以访问
http.authorizeRequests().mvcMatchers(permission.getResource()).hasAnyAuthority(permission.getExpression());
}
配置相关的配置
http.authorizeRequests()//授权配置
.mvcMatchers("/login","/login.html").permitAll()//放行/longin登录路径
.anyRequest().authenticated()//其他的请求都要认证以后才可以访问
.and().formLogin()//允许表单登录
.loginPage("/login.html")//自定义登录页面
.loginProcessingUrl("/login")//自定义登录提交路径
.successForwardUrl("/loginSuccess")
.and().logout().permitAll()//注销路径放行
.and().csrf().disable();//关闭跨域伪造检查
自定义登出 定义一个类MyLogoutHandler 继承LogoutSuccessHandler 复写方法
public class MyLogoutHandler implements org.springframework.security.web.authentication.logout.LogoutSuccessHandler {
@Override
public void onLogoutSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
System.out.println("自定义注销");
}
}
- SpringSecurity提供了默认的退出处理,可以在Security配置类中通过.and().logout().permitAll(); 使用默认的退出路径“/logout” ,如果我们需要自定义退出路径,可以通过如下方式指定:
.and().logout().logoutUrl("/mylogout").permitAll() //制定义登出路径
.logoutSuccessHandler(new MyLogoutHandler()) //登出后处理器-可以做一些额外的事情
.invalidateHttpSession(true); //登出后session无效
注意:要对登录页面放行,数据库密码密文保存,mapper和xml省略