mirror of
https://github.com/RemainderTime/spring-boot-base-demo.git
synced 2026-05-26 04:27:48 +08:00
登录时查询用户权限和角色并加载到Spring Security的上下文中
This commit is contained in:
@@ -6,6 +6,7 @@ import org.springframework.http.HttpHeaders;
|
|||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.HttpStatusCode;
|
import org.springframework.http.HttpStatusCode;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.security.access.AccessDeniedException;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
@@ -84,6 +85,19 @@ public class GlobalExceptionHandler extends ResponseEntityExceptionHandler{
|
|||||||
return new ResponseEntity<>(errors, HttpStatus.BAD_REQUEST);
|
return new ResponseEntity<>(errors, HttpStatus.BAD_REQUEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 访问权限不足异常捕获
|
||||||
|
* @param e
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@ExceptionHandler(AccessDeniedException.class)
|
||||||
|
public ResponseEntity handleAccessDenied(AccessDeniedException e) {
|
||||||
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
result.put("code", 403);
|
||||||
|
result.put("msg", "权限不足,请联系管理员");
|
||||||
|
return ResponseEntity.status(HttpStatus.FORBIDDEN).body(result);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 其他异常捕获
|
* 其他异常捕获
|
||||||
* @param request
|
* @param request
|
||||||
|
|||||||
@@ -37,11 +37,6 @@ public class CustomUserDetails implements UserDetails {
|
|||||||
this.authorities = authorities;
|
this.authorities = authorities;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<? extends GrantedAuthority> getAuthorities() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getPassword() {
|
public String getPassword() {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -1,29 +1,32 @@
|
|||||||
package cn.xf.basedemo.config;
|
//package cn.xf.basedemo.config;
|
||||||
|
//
|
||||||
import lombok.extern.slf4j.Slf4j;
|
//import cn.xf.basedemo.interceptor.CustomAccessDeniedHandler;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
//import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
//import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
import org.springframework.context.annotation.Bean;
|
//import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
//import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.security.config.Customizer;
|
//import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
//import org.springframework.security.config.Customizer;
|
||||||
import org.springframework.security.web.SecurityFilterChain;
|
//import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
||||||
import org.springframework.web.cors.CorsConfiguration;
|
//import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
import org.springframework.web.cors.CorsConfigurationSource;
|
//import org.springframework.security.web.SecurityFilterChain;
|
||||||
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
//import org.springframework.web.cors.CorsConfiguration;
|
||||||
import org.springframework.web.filter.CorsFilter;
|
//import org.springframework.web.cors.CorsConfigurationSource;
|
||||||
|
//import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
||||||
/**
|
//import org.springframework.web.filter.CorsFilter;
|
||||||
* Description: 全局跨域配置
|
//
|
||||||
*
|
///**
|
||||||
*/
|
// * Description: 全局跨域配置
|
||||||
@Slf4j
|
// *
|
||||||
@Configuration
|
// */
|
||||||
public class GlobalCorsConfig {
|
//@Slf4j
|
||||||
|
//@Configuration
|
||||||
|
//@EnableMethodSecurity(prePostEnabled = true) // 开启 @PreAuthorize/@PostAuthorize
|
||||||
|
//public class GlobalCorsConfig {
|
||||||
|
//
|
||||||
// @ConditionalOnMissingBean
|
// @ConditionalOnMissingBean
|
||||||
// @Bean
|
// @Bean
|
||||||
// public CorsFilter corsFilter() {
|
// public FilterRegistrationBean<CorsFilter> corsFilter() {
|
||||||
// CorsConfiguration config = new CorsConfiguration();
|
// CorsConfiguration config = new CorsConfiguration();
|
||||||
// // 放行哪些原始域
|
// // 放行哪些原始域
|
||||||
// //config.addAllowedOrigin("*");
|
// //config.addAllowedOrigin("*");
|
||||||
@@ -39,36 +42,10 @@ public class GlobalCorsConfig {
|
|||||||
// UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
|
// UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
|
||||||
// configSource.registerCorsConfiguration("/**", config);
|
// configSource.registerCorsConfiguration("/**", config);
|
||||||
//
|
//
|
||||||
//// FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(configSource));
|
// FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(configSource));
|
||||||
// // 这个顺序很重要哦,为避免麻烦请设置在最前
|
// // 这个顺序很重要哦,为避免麻烦请设置在最前
|
||||||
//// bean.setOrder(0);
|
// bean.setOrder(0);
|
||||||
// return new CorsFilter(configSource);
|
// return bean;
|
||||||
// }
|
// }
|
||||||
|
//
|
||||||
@Bean
|
//}
|
||||||
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
|
|
||||||
http
|
|
||||||
.cors(Customizer.withDefaults()) // 开启 CORS
|
|
||||||
.csrf(csrf -> csrf.disable())
|
|
||||||
.authorizeHttpRequests(auth -> auth
|
|
||||||
.requestMatchers("/user/login", "/web/**").permitAll() // 放行登录、注册接口
|
|
||||||
.anyRequest().authenticated()
|
|
||||||
);
|
|
||||||
|
|
||||||
return http.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public CorsConfigurationSource corsConfigurationSource() {
|
|
||||||
CorsConfiguration config = new CorsConfiguration();
|
|
||||||
config.addAllowedOriginPattern("*");
|
|
||||||
config.addAllowedHeader("*");
|
|
||||||
config.addAllowedMethod("*");
|
|
||||||
config.setAllowCredentials(true);
|
|
||||||
|
|
||||||
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
|
||||||
source.registerCorsConfiguration("/**", config);
|
|
||||||
return source;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package cn.xf.basedemo.config.security;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.security.config.Customizer;
|
||||||
|
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
||||||
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
|
import org.springframework.security.web.SecurityFilterChain;
|
||||||
|
import org.springframework.web.cors.CorsConfiguration;
|
||||||
|
import org.springframework.web.cors.CorsConfigurationSource;
|
||||||
|
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description: spring security体系 全局跨域配置
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Configuration
|
||||||
|
@EnableMethodSecurity(prePostEnabled = true) // 开启 @PreAuthorize/@PostAuthorize
|
||||||
|
public class SpringSecurityConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
|
||||||
|
http
|
||||||
|
.cors(Customizer.withDefaults()) // 开启 CORS
|
||||||
|
.csrf(csrf -> csrf.disable())
|
||||||
|
.authorizeHttpRequests(auth -> auth
|
||||||
|
.requestMatchers("/**", "/web/**").permitAll() // 放行登录、注册接口
|
||||||
|
.anyRequest().authenticated()
|
||||||
|
);
|
||||||
|
|
||||||
|
return http.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public CorsConfigurationSource corsConfigurationSource() {
|
||||||
|
CorsConfiguration config = new CorsConfiguration();
|
||||||
|
config.addAllowedOriginPattern("*");
|
||||||
|
config.addAllowedHeader("*");
|
||||||
|
config.addAllowedMethod("*");
|
||||||
|
config.setAllowCredentials(true);
|
||||||
|
|
||||||
|
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
||||||
|
source.registerCorsConfiguration("/**", config);
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -40,8 +40,10 @@ public class UserController {
|
|||||||
@PostMapping("/info")
|
@PostMapping("/info")
|
||||||
@PreAuthorize("hasAuthority('user:add')") // 权限控制
|
@PreAuthorize("hasAuthority('user:add')") // 权限控制
|
||||||
public RetObj info(){
|
public RetObj info(){
|
||||||
LoginUser loginUser = SessionContext.getInstance().get();
|
// LoginUser loginUser = SessionContext.getInstance().get();
|
||||||
return RetObj.success(loginUser);
|
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
|
||||||
|
CustomUserDetails user = (CustomUserDetails) auth.getPrincipal();
|
||||||
|
return RetObj.success(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "es同步用户信息", description = "用户信息")
|
@Operation(summary = "es同步用户信息", description = "用户信息")
|
||||||
@@ -56,7 +58,6 @@ public class UserController {
|
|||||||
public RetObj getEsId(Long userId){
|
public RetObj getEsId(Long userId){
|
||||||
return userService.getEsId(userId);
|
return userService.getEsId(userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "获取用户权限数据", description = "用户信息")
|
@Operation(summary = "获取用户权限数据", description = "用户信息")
|
||||||
@GetMapping("/getPermission")
|
@GetMapping("/getPermission")
|
||||||
public RetObj getPermission(){
|
public RetObj getPermission(){
|
||||||
@@ -65,4 +66,5 @@ public class UserController {
|
|||||||
return RetObj.success(user.getAuthorities());
|
return RetObj.success(user.getAuthorities());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,120 @@
|
|||||||
|
package cn.xf.basedemo.interceptor;
|
||||||
|
|
||||||
|
import cn.xf.basedemo.common.exception.LoginException;
|
||||||
|
import cn.xf.basedemo.common.exception.ResponseCode;
|
||||||
|
import cn.xf.basedemo.common.model.CustomUserDetails;
|
||||||
|
import cn.xf.basedemo.common.model.LoginUser;
|
||||||
|
import cn.xf.basedemo.common.utils.ApplicationContextUtils;
|
||||||
|
import cn.xf.basedemo.mappers.SysPermissionMapper;
|
||||||
|
import cn.xf.basedemo.mappers.SysRoleMapper;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import jakarta.servlet.FilterChain;
|
||||||
|
import jakarta.servlet.ServletException;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
|
import org.springframework.security.core.authority.AuthorityUtils;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
import org.springframework.web.filter.OncePerRequestFilter;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description: 登录权限校验过滤器(过滤器职责:登录认证和权限恢复)
|
||||||
|
* @ClassName: TokenAuthenticationFilter
|
||||||
|
* @Author: xiongfeng
|
||||||
|
* @Date: 2025/8/28 22:41
|
||||||
|
* @Version: 1.0
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class TokenAuthenticationFilter extends OncePerRequestFilter {
|
||||||
|
|
||||||
|
//不拦截的请求列表
|
||||||
|
private static final List<String> EXCLUDE_PATH_LIST = Arrays.asList("/user/login", "/web/login", "/swagger-ui.html", "/v3/api-docs", "/swagger-ui/index.html");
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RedisTemplate redisTemplate;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SysPermissionMapper sysPermissionMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SysRoleMapper sysRoleMapper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
|
||||||
|
//登录处理
|
||||||
|
try {
|
||||||
|
String requestURI = request.getRequestURI();
|
||||||
|
if (EXCLUDE_PATH_LIST.contains(requestURI) ||
|
||||||
|
requestURI.contains("/swagger-ui") ||
|
||||||
|
requestURI.contains("/v3/api-docs")) {
|
||||||
|
filterChain.doFilter(request, response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String token = request.getHeader("Authorization");
|
||||||
|
if (StringUtils.isEmpty(token))
|
||||||
|
token = request.getParameter("token");
|
||||||
|
if (StringUtils.isEmpty(token)) {
|
||||||
|
throw new LoginException("请先登录");
|
||||||
|
}
|
||||||
|
String value = (String) redisTemplate.opsForValue().get("token:" + token);
|
||||||
|
if (StringUtils.isEmpty(value)) {
|
||||||
|
throw new LoginException();
|
||||||
|
}
|
||||||
|
JSONObject jsonObject = JSONObject.parseObject(value);
|
||||||
|
//JSON对象转换成Java对象
|
||||||
|
LoginUser loginUserInfo = JSONObject.toJavaObject(jsonObject, LoginUser.class);
|
||||||
|
if (loginUserInfo == null || loginUserInfo.getId() <= 0) {
|
||||||
|
throw new LoginException(ResponseCode.USER_INPUT_ERROR);
|
||||||
|
}
|
||||||
|
redisTemplate.expire(token, 86700, TimeUnit.SECONDS);
|
||||||
|
//用户信息设置到上下文(如果使用Spring security 也可设置登录用户上下文数据,下面就可不用自定义设置)
|
||||||
|
SessionContext.getInstance().set(loginUserInfo);
|
||||||
|
//设置用户权限角色
|
||||||
|
this.setSpringSecurityContext(loginUserInfo);
|
||||||
|
filterChain.doFilter(request, response);
|
||||||
|
}catch (LoginException e) {
|
||||||
|
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
|
||||||
|
response.setContentType("application/json;charset=UTF-8");
|
||||||
|
response.getWriter().write("{\"message\":\"" + e.getMessage() + "\"}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Authentication auth = SecurityContextHolder.getContext().getAuthentication();
|
||||||
|
// CustomUserDetails user = (CustomUserDetails) auth.getPrincipal();
|
||||||
|
// Long userId = user.getUserId(); // 拿到登录用户 ID
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置用户权限角色 (Spring Security 本身的 SecurityContext 是请求级别的,每次请求都会被清理,所以每次请求都会查询权限数据并设置,
|
||||||
|
* 安全但是很慢,所以可以做一些优化,比如把权限数据放到redis中获取和用户信息一起放在jwt中,然后登录时解析在设置到Spring security上下文中)
|
||||||
|
* @param loginUserInfo
|
||||||
|
*/
|
||||||
|
private void setSpringSecurityContext(LoginUser loginUserInfo) {
|
||||||
|
//获取登录用户权限数据
|
||||||
|
List<String> permissionList = sysPermissionMapper.getPermissionListByRoleId(loginUserInfo.getId());
|
||||||
|
//获取用户角色数据
|
||||||
|
List<String> roleList = sysRoleMapper.getRoleListByUserId(loginUserInfo.getId());
|
||||||
|
if (!CollectionUtils.isEmpty(roleList)) {
|
||||||
|
//为角色拼接前缀
|
||||||
|
roleList = roleList.stream().map(role -> "ROLE_" + role).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
permissionList.addAll(roleList);
|
||||||
|
//封装用户权限角色
|
||||||
|
List<GrantedAuthority> authorities = AuthorityUtils.createAuthorityList(permissionList);
|
||||||
|
//设置用户信息到SpringSecurity上下文
|
||||||
|
UserDetails userDetails = new CustomUserDetails(loginUserInfo.getId(), loginUserInfo.getPhone(), authorities);
|
||||||
|
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
|
||||||
|
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -35,20 +35,13 @@ import java.util.stream.Collectors;
|
|||||||
/**
|
/**
|
||||||
* @program: spring-boot-base-demo
|
* @program: spring-boot-base-demo
|
||||||
* @ClassName TokenInterceptor
|
* @ClassName TokenInterceptor
|
||||||
* @description:
|
* @description: 拦截器职责(日志、请求校验、限流)
|
||||||
* @author: xiongfeng
|
* @author: xiongfeng
|
||||||
* @create: 2022-06-16 14:17
|
* @create: 2022-06-16 14:17
|
||||||
**/
|
**/
|
||||||
@Component
|
@Component
|
||||||
public class TokenInterceptor implements HandlerInterceptor {
|
public class TokenInterceptor implements HandlerInterceptor {
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private RedisTemplate redisTemplate;
|
|
||||||
|
|
||||||
private SysPermissionMapper sysPermissionMapper = ApplicationContextUtils.getBean(SysPermissionMapper.class);
|
|
||||||
private SysRoleMapper sysRoleMapper = ApplicationContextUtils.getBean(SysRoleMapper.class);
|
|
||||||
|
|
||||||
|
|
||||||
//不拦截的请求列表
|
//不拦截的请求列表
|
||||||
private static final List<String> EXCLUDE_PATH_LIST = Arrays.asList("/user/login", "/web/login", "/swagger-ui.html", "/v3/api-docs", "/swagger-ui/index.html");
|
private static final List<String> EXCLUDE_PATH_LIST = Arrays.asList("/user/login", "/web/login", "/swagger-ui.html", "/v3/api-docs", "/swagger-ui/index.html");
|
||||||
|
|
||||||
@@ -61,33 +54,8 @@ public class TokenInterceptor implements HandlerInterceptor {
|
|||||||
requestURI.contains("/v3/api-docs")) {
|
requestURI.contains("/v3/api-docs")) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//登录处理
|
|
||||||
String token = request.getHeader("Authorization");
|
|
||||||
if (StringUtils.isEmpty(token))
|
|
||||||
token = request.getParameter("token");
|
|
||||||
if (StringUtils.isEmpty(token)) {
|
|
||||||
throw new LoginException("请先登录");
|
|
||||||
}
|
|
||||||
String value = (String) redisTemplate.opsForValue().get("token:" + token);
|
|
||||||
if (StringUtils.isEmpty(value)) {
|
|
||||||
throw new LoginException();
|
|
||||||
}
|
|
||||||
JSONObject jsonObject = JSONObject.parseObject(value);
|
|
||||||
//JSON对象转换成Java对象
|
|
||||||
LoginUser loginUserInfo = JSONObject.toJavaObject(jsonObject, LoginUser.class);
|
|
||||||
if (loginUserInfo == null || loginUserInfo.getId() <= 0) {
|
|
||||||
throw new LoginException(ResponseCode.USER_INPUT_ERROR);
|
|
||||||
}
|
|
||||||
redisTemplate.expire(token, 86700, TimeUnit.SECONDS);
|
|
||||||
//设置用户权限角色
|
|
||||||
this.setSpringSecurityContext(loginUserInfo);
|
|
||||||
//用户信息设置到上下文(如果使用Spring security 也可设置登录用户上下文数据,下面就可不用自定义设置)
|
|
||||||
SessionContext.getInstance().set(loginUserInfo);
|
|
||||||
return HandlerInterceptor.super.preHandle(request, response, handler);
|
return HandlerInterceptor.super.preHandle(request, response, handler);
|
||||||
}
|
}
|
||||||
// Authentication auth = SecurityContextHolder.getContext().getAuthentication();
|
|
||||||
// CustomUserDetails user = (CustomUserDetails) auth.getPrincipal();
|
|
||||||
// Long userId = user.getUserId(); // 拿到登录用户 ID
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
|
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
|
||||||
@@ -95,26 +63,5 @@ public class TokenInterceptor implements HandlerInterceptor {
|
|||||||
SessionContext.getInstance().clear();
|
SessionContext.getInstance().clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置用户权限角色 (Spring Security 本身的 SecurityContext 是请求级别的,每次请求都会被清理,所以每次请求都会查询权限数据并设置,
|
|
||||||
* 安全但是很慢,所以可以做一些优化,比如把权限数据放到redis中获取和用户信息一起放在jwt中,然后登录时解析在设置到Spring security上下文中)
|
|
||||||
* @param loginUserInfo
|
|
||||||
*/
|
|
||||||
private void setSpringSecurityContext(LoginUser loginUserInfo) {
|
|
||||||
//获取登录用户权限数据
|
|
||||||
List<String> permissionList = sysPermissionMapper.getPermissionListByRoleId(loginUserInfo.getId());
|
|
||||||
//获取用户角色数据
|
|
||||||
List<String> roleList = sysRoleMapper.getRoleListByUserId(loginUserInfo.getId());
|
|
||||||
if (!CollectionUtils.isEmpty(roleList)) {
|
|
||||||
//为角色拼接前缀
|
|
||||||
roleList = roleList.stream().map(role -> "ROLE_" + role).collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
permissionList.addAll(roleList);
|
|
||||||
//封装用户权限角色
|
|
||||||
List<GrantedAuthority> authorities = AuthorityUtils.createAuthorityList(permissionList);
|
|
||||||
//设置用户信息到SpringSecurity上下文
|
|
||||||
UserDetails userDetails = new CustomUserDetails(loginUserInfo.getId(), loginUserInfo.getPhone(), authorities);
|
|
||||||
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
|
|
||||||
SecurityContextHolder.getContext().setAuthentication(authentication);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user