|
|
@@ -0,0 +1,82 @@
|
|
|
+package shop.alien.store.filter;
|
|
|
+
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
|
|
+import org.springframework.security.core.authority.AuthorityUtils;
|
|
|
+import org.springframework.security.core.context.SecurityContextHolder;
|
|
|
+import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
+import org.springframework.web.filter.OncePerRequestFilter;
|
|
|
+import shop.alien.entity.store.LifeSysMenu;
|
|
|
+import shop.alien.entity.store.LifeSysRole;
|
|
|
+import shop.alien.mapper.LifeSysMenuMapper;
|
|
|
+import shop.alien.store.service.impl.LifeSysRoleServiceImpl;
|
|
|
+import shop.alien.util.common.JwtUtil;
|
|
|
+
|
|
|
+import javax.annotation.Resource;
|
|
|
+import javax.servlet.FilterChain;
|
|
|
+import javax.servlet.ServletException;
|
|
|
+import javax.servlet.http.HttpServletRequest;
|
|
|
+import javax.servlet.http.HttpServletResponse;
|
|
|
+import java.io.IOException;
|
|
|
+import java.util.List;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+@Component
|
|
|
+public class PreAuthFilter extends OncePerRequestFilter {
|
|
|
+ // 自定义权限请求头(前端传递角色/权限)
|
|
|
+ private static final String USER_TOKEN_HEADER = "Authorization";
|
|
|
+ private static final String PLATFORM_TYPE_HEADER = "X-platform-type";
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private LifeSysMenuMapper lifeSysMenuMapper;
|
|
|
+ @Resource
|
|
|
+ private LifeSysRoleServiceImpl lifeSysRoleServiceImpl;
|
|
|
+ @Override
|
|
|
+ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
|
|
|
+ throws ServletException, IOException {
|
|
|
+ // 1. 从请求头获取角色信息(前端传递,比如:ROLE_ADMIN,ROLE_USER)
|
|
|
+ String token = request.getHeader(USER_TOKEN_HEADER);
|
|
|
+ String platformType = request.getHeader(PLATFORM_TYPE_HEADER);
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 如果不是平台端请求,直接放行,加admin权放行
|
|
|
+ */
|
|
|
+ if(null != platformType || "platform".equalsIgnoreCase(platformType)) {
|
|
|
+ UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(
|
|
|
+ "notPlatformUser", // 无认证场景,用户名可自定义
|
|
|
+ null, // 无需密码,置空
|
|
|
+ AuthorityUtils.commaSeparatedStringToAuthorityList(String.join(",", "ROLE_ADMIN")));// 权限列表
|
|
|
+ chain.doFilter(request, response);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (token == null) {
|
|
|
+ // 无权限头:视为匿名用户(仅能访问公开接口)
|
|
|
+ chain.doFilter(request, response);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 解析角色为权限集合(Spring Security 角色需以ROLE_开头)
|
|
|
+ JSONObject tokenInfo = JwtUtil.getTokenInfo(token);
|
|
|
+ String userId = tokenInfo.getString("userId");
|
|
|
+ String userName = tokenInfo.getString("userName");
|
|
|
+ List<LifeSysMenu> menuByUserId = lifeSysMenuMapper.getMenuByUserId(Long.parseLong(userId));
|
|
|
+ List<String> permsList = menuByUserId.stream().map(LifeSysMenu::getPerms).collect(Collectors.toList());
|
|
|
+ List<LifeSysRole> roleByUserId = lifeSysRoleServiceImpl.getRoleByUserId(Long.parseLong(userId));
|
|
|
+ List<String> roleList = roleByUserId.stream().map(x->"ROLE_"+x.getRoleNameEn().toUpperCase()).collect(Collectors.toList());
|
|
|
+ permsList.addAll(roleList);
|
|
|
+ // 3. 构建认证令牌(用户名可固定/自定义,密码置空,核心是权限)
|
|
|
+ UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(
|
|
|
+ userName, // 无认证场景,用户名可自定义
|
|
|
+ null, // 无需密码,置空
|
|
|
+ AuthorityUtils.commaSeparatedStringToAuthorityList(String.join(",", permsList)));// 权限列表
|
|
|
+ // 4. 设置请求上下文
|
|
|
+ authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
|
|
|
+ // 5. 将认证信息存入SecurityContext(标记用户已"认证",仅用于授权)
|
|
|
+ SecurityContextHolder.getContext().setAuthentication(authToken);
|
|
|
+
|
|
|
+ // 继续执行过滤器链
|
|
|
+ chain.doFilter(request, response);
|
|
|
+ }
|
|
|
+}
|