潘志宝
2024-12-23 5bf42aa9950058f391805e6fb8d7376f4378924b
提交 | 用户 | 时间
e7c126 1 package com.iailab.gateway.util;
H 2
3 import cn.hutool.core.map.MapUtil;
4 import com.iailab.framework.common.util.json.JsonUtils;
5 import com.iailab.gateway.filter.security.LoginUser;
6 import lombok.SneakyThrows;
7 import lombok.extern.slf4j.Slf4j;
8 import org.springframework.http.server.reactive.ServerHttpRequest;
9 import org.springframework.util.StringUtils;
10 import org.springframework.web.server.ServerWebExchange;
11
12 import java.io.UnsupportedEncodingException;
13 import java.net.URLEncoder;
14 import java.nio.charset.StandardCharsets;
15
16 /**
17  * 安全服务工具类
18  *
19  * copy from iailab-common-security 的 SecurityFrameworkUtils 类
20  *
21  * @author iailab
22  */
23 @Slf4j
24 public class SecurityFrameworkUtils {
25
26     private static final String AUTHORIZATION_HEADER = "Authorization";
27
28     private static final String AUTHORIZATION_BEARER = "Bearer";
29
30     private static final String LOGIN_USER_HEADER = "login-user";
31
32     private static final String LOGIN_USER_ID_ATTR = "login-user-id";
33     private static final String LOGIN_USER_TYPE_ATTR = "login-user-type";
34
35     private SecurityFrameworkUtils() {}
36
37     /**
38      * 从请求中,获得认证 Token
39      *
40      * @param exchange 请求
41      * @return 认证 Token
42      */
43     public static String obtainAuthorization(ServerWebExchange exchange) {
44         String authorization = exchange.getRequest().getHeaders().getFirst(AUTHORIZATION_HEADER);
45         if (!StringUtils.hasText(authorization)) {
46             return null;
47         }
48         int index = authorization.indexOf(AUTHORIZATION_BEARER + " ");
49         if (index == -1) { // 未找到
50             return null;
51         }
52         return authorization.substring(index + 7).trim();
53     }
54
55     /**
56      * 设置登录用户
57      *
58      * @param exchange 请求
59      * @param user 用户
60      */
61     public static void setLoginUser(ServerWebExchange exchange, LoginUser user) {
62         exchange.getAttributes().put(LOGIN_USER_ID_ATTR, user.getId());
63         exchange.getAttributes().put(LOGIN_USER_TYPE_ATTR, user.getUserType());
64     }
65
66     /**
67      * 移除请求头的用户
68      *
69      * @param exchange 请求
70      * @return 请求
71      */
72     public static ServerWebExchange removeLoginUser(ServerWebExchange exchange) {
73         // 如果不包含,直接返回
74         if (!exchange.getRequest().getHeaders().containsKey(LOGIN_USER_HEADER)) {
75             return exchange;
76         }
77         // 如果包含,则移除。参考 RemoveRequestHeaderGatewayFilterFactory 实现
78         ServerHttpRequest request = exchange.getRequest().mutate()
79                 .headers(httpHeaders -> httpHeaders.remove(LOGIN_USER_HEADER)).build();
80         return exchange.mutate().request(request).build();
81     }
82
83     /**
84      * 获得登录用户的编号
85      *
86      * @param exchange 请求
87      * @return 用户编号
88      */
89     public static Long getLoginUserId(ServerWebExchange exchange) {
90         return MapUtil.getLong(exchange.getAttributes(), LOGIN_USER_ID_ATTR);
91     }
92
93     /**
94      * 获得登录用户的类型
95      *
96      * @param exchange 请求
97      * @return 用户类型
98      */
99     public static Integer getLoginUserType(ServerWebExchange exchange) {
100         return MapUtil.getInt(exchange.getAttributes(), LOGIN_USER_TYPE_ATTR);
101     }
102
103     /**
104      * 将 user 并设置到 login-user 的请求头,使用 json 存储值
105      *
106      * @param builder 请求
107      * @param user 用户
108      */
109     @SneakyThrows
110     public static void setLoginUserHeader(ServerHttpRequest.Builder builder, LoginUser user) {
111         try {
112             String userStr = JsonUtils.toJsonString(user);
113             userStr = URLEncoder.encode(userStr, StandardCharsets.UTF_8.name()); // 编码,避免中文乱码
114             builder.header(LOGIN_USER_HEADER, userStr);
115         } catch (Exception ex) {
116             log.error("[setLoginUserHeader][序列化 user({}) 发生异常]", user, ex);
117             throw ex;
118         }
119     }
120
121 }