dengzedong
2024-12-31 90a1495b9d765c9e1d48f689dbcf977cbdb2768e
提交 | 用户 | 时间
e7c126 1 package com.iailab.framework.security.core.util;
H 2
3 import cn.hutool.core.map.MapUtil;
4 import cn.hutool.core.util.StrUtil;
5 import com.iailab.framework.security.core.LoginUser;
6 import com.iailab.framework.web.core.util.WebFrameworkUtils;
7 import org.springframework.lang.Nullable;
8 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
9 import org.springframework.security.core.Authentication;
10 import org.springframework.security.core.context.SecurityContext;
11 import org.springframework.security.core.context.SecurityContextHolder;
12 import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
13 import org.springframework.util.StringUtils;
14
15 import javax.servlet.http.HttpServletRequest;
16 import java.util.Collections;
17
18 /**
19  * 安全服务工具类
20  *
21  * @author iailab
22  */
23 public class SecurityFrameworkUtils {
24
25     /**
26      * HEADER 认证头 value 的前缀
27      */
28     public static final String AUTHORIZATION_BEARER = "Bearer";
29
30     public static final String LOGIN_USER_HEADER = "login-user";
31
32     private SecurityFrameworkUtils() {}
33
34     /**
35      * 从请求中,获得认证 Token
36      *
37      * @param request 请求
38      * @param headerName 认证 Token 对应的 Header 名字
39      * @param parameterName 认证 Token 对应的 Parameter 名字
40      * @return 认证 Token
41      */
42     public static String obtainAuthorization(HttpServletRequest request,
43                                              String headerName, String parameterName) {
44         // 1. 获得 Token。优先级:Header > Parameter
45         String token = request.getHeader(headerName);
46         if (StrUtil.isEmpty(token)) {
47             token = request.getParameter(parameterName);
48         }
49         if (!StringUtils.hasText(token)) {
50             return null;
51         }
52         // 2. 去除 Token 中带的 Bearer
53         int index = token.indexOf(AUTHORIZATION_BEARER + " ");
54         return index >= 0 ? token.substring(index + 7).trim() : token;
55     }
56
57     /**
58      * 获得当前认证信息
59      *
60      * @return 认证信息
61      */
62     public static Authentication getAuthentication() {
63         SecurityContext context = SecurityContextHolder.getContext();
64         if (context == null) {
65             return null;
66         }
67         return context.getAuthentication();
68     }
69
70     /**
71      * 获取当前用户
72      *
73      * @return 当前用户
74      */
75     @Nullable
76     public static LoginUser getLoginUser() {
77         Authentication authentication = getAuthentication();
78         if (authentication == null) {
79             return null;
80         }
81         return authentication.getPrincipal() instanceof LoginUser ? (LoginUser) authentication.getPrincipal() : null;
82     }
83
84     /**
85      * 获得当前用户的编号,从上下文中
86      *
87      * @return 用户编号
88      */
89     @Nullable
90     public static Long getLoginUserId() {
91         LoginUser loginUser = getLoginUser();
92         return loginUser != null ? loginUser.getId() : null;
93     }
94
95     /**
96      * 获得当前用户的昵称,从上下文中
97      *
98      * @return 昵称
99      */
100     @Nullable
101     public static String getLoginUserNickname() {
102         LoginUser loginUser = getLoginUser();
103         return loginUser != null ? MapUtil.getStr(loginUser.getInfo(), LoginUser.INFO_KEY_NICKNAME) : null;
104     }
105
106     /**
107      * 获得当前用户的部门编号,从上下文中
108      *
109      * @return 部门编号
110      */
111     @Nullable
112     public static Long getLoginUserDeptId() {
113         LoginUser loginUser = getLoginUser();
114         return loginUser != null ? MapUtil.getLong(loginUser.getInfo(), LoginUser.INFO_KEY_DEPT_ID) : null;
115     }
116
117     /**
118      * 设置当前用户
119      *
120      * @param loginUser 登录用户
121      * @param request 请求
122      */
123     public static void setLoginUser(LoginUser loginUser, HttpServletRequest request) {
124         // 创建 Authentication,并设置到上下文
125         Authentication authentication = buildAuthentication(loginUser, request);
126         SecurityContextHolder.getContext().setAuthentication(authentication);
127
128         // 额外设置到 request 中,用于 ApiAccessLogFilter 可以获取到用户编号;
129         // 原因是,Spring Security 的 Filter 在 ApiAccessLogFilter 后面,在它记录访问日志时,线上上下文已经没有用户编号等信息
130         WebFrameworkUtils.setLoginUserId(request, loginUser.getId());
131         WebFrameworkUtils.setLoginUserType(request, loginUser.getUserType());
132     }
133
134     private static Authentication buildAuthentication(LoginUser loginUser, HttpServletRequest request) {
135         // 创建 UsernamePasswordAuthenticationToken 对象
136         UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(
137                 loginUser, null, Collections.emptyList());
138         authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
139         return authenticationToken;
140     }
141
142 }