目录
一、SpringSecurity集成10.md
1 添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
2 SecurityConfig配置类
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder(){
return new BCryptPasswordEncoder();
}
public static void main(String[] args) {
//加密策略 MD5 不安全 彩虹表 MD5 加盐
String mszlu = new BCryptPasswordEncoder().encode("mszlu");
System.out.println(mszlu);
}
@Override
public void configure(WebSecurity web) throws Exception {
super.configure(web);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests() //开启登录认证
// .antMatchers("/user/findAll").hasRole("admin") //访问接口需要admin的角色
.antMatchers("/css/**").permitAll()
.antMatchers("/img/**").permitAll()
.antMatchers("/js/**").permitAll()
.antMatchers("/plugins/**").permitAll()
.antMatchers("/admin/**").access("@authService.auth(request,authentication)") //自定义service 来去实现实时的权限认证
.antMatchers("/pages/**").authenticated()
.and().formLogin()
.loginPage("/login.html") //自定义的登录页面
.loginProcessingUrl("/login") //登录处理接口
.usernameParameter("username") //定义登录时的用户名的key 默认为username
.passwordParameter("password") //定义登录时的密码key,默认是password
.defaultSuccessUrl("/pages/main.html")
.failureUrl("/login.html")
.permitAll() //通过 不拦截,更加前面配的路径决定,这是指和登录表单相关的接口 都通过
.and().logout() //退出登录配置
.logoutUrl("/logout") //退出登录接口
.logoutSuccessUrl("/login.html")
.permitAll() //退出登录的接口放行
.and()
.httpBasic()
.and()
.csrf().disable() //csrf关闭 如果自定义登录 需要关闭
.headers().frameOptions().sameOrigin();
}
}
二、登录认证和权限管理
1、登录认证
前端表单传来用户名和密码,后端会通过SpringSecurity进行处理核对
@Service
@Slf4j
public class SecurityUserService implements UserDetailsService {
@Autowired
private AdminService adminService;
/**
* 登录认证:
* //接收登录时的username
* //通过username查询admin表。若存在,将密码传给SpringSecurity
* //若不存在,返回null,登录认证失败
* @param username
* @return
* @throws UsernameNotFoundException
*/
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
//当用户登录的时候,springSecurity 就会将请求 转发到此
//根据用户名 查找用户,不存在 抛出异常,存在 将用户名,密码,授权列表 组装成springSecurity的User对象 并返回
//通过username查询admin表
Admin admin = adminService.findAdminByUsername(username);
if (admin == null){
log.info("用户不存在,登录失败");
return null;
}
//用户存在,返回密码给SpringSecurity,让其验证密码是否正确
//通过UserDetails接收需要验证的信息
//因UserDetails是接口 不能直接new,在此new其实现类
User userDetails = new User(username, admin.getPassword(), new ArrayList<>());//此处集合是认证授权列表,因我们在此不做认证授权,所以暂时给空列表
return userDetails;
}
}
2、权限管理
认证成功之后,在进行操作时,需要验证用户是否有该操作权限
所以编写上图中的方法即可
@Service
@Slf4j
public class AuthService {
@Autowired
private AdminService adminService;
/**
* 判断是否有权限:通过Authentication获取用户信息,通过信息中的id查询其在数据库中对应的信息
* 1、获取请求路径与数据库存储路径对比
* @param request
* @param authentication
*/
public boolean auth(HttpServletRequest request, Authentication authentication){
//获取请求路径
String requestURI = request.getRequestURI();
//请求路径可能包含?id=...,需截取
requestURI = StringUtils.split(requestURI,'?')[0];
log.info("请求路径request url:{}", requestURI);
//获取当前登录的用户信息
Object principal = authentication.getPrincipal();
//判断当前用户信息是否为空获取是否为匿名用户
if (principal == null || "anonymousUser".equals(principal)){
//未登录
return false;
}
//用户信息真实存在的话就转为UserDetails便于使用
UserDetails userDetails = (UserDetails) principal;
String username = userDetails.getUsername();
//通过用户名获取admin
Admin admin = adminService.findAdminByUsername(username);
if (admin == null){
return false;
}
if (admin.getId() == 1){
//认为是超级管理员
return true;
}
List<Permission> permissions = adminService.findPermissionByAdminId(admin.getId());
for (Permission permission : permissions) {
if (requestURI.equals(permission.getPath())){
log.info("权限认证通过");
return true;
}
}
return false;
}
}
全项目技术亮点:
线程安全:cas操作
线程池:1、核心线程数 2、最大线程数 3、线程存活时间 (针对救急线程)4、时间单位 5、线程工厂6、阻塞队列 7、拒绝策略