mirror of
http://git.pig4cloud.com/pig/pigx.git
synced 2026-11-08 12:39:05 +08:00
refactor(security): 增加 satoken 通用配置属性
This commit is contained in:
1 parent
bc305ca84a
commit
e77e2c5a4a
2 files changed
+215
-171
No files matched your search
+208
-171
@@ -22,8 +22,13 @@ package com.pig4cloud.pigx.common.core.util;
|
||||
import cn.hutool.core.codec.Base64;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import jakarta.servlet.http.Cookie;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
@@ -32,12 +37,10 @@ import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
|
||||
import jakarta.servlet.http.Cookie;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
@@ -49,191 +52,225 @@ import java.util.Optional;
|
||||
@UtilityClass
|
||||
public class WebUtils extends org.springframework.web.util.WebUtils {
|
||||
|
||||
private final String BASIC_ = "Basic ";
|
||||
private final String BASIC_ = "Basic ";
|
||||
|
||||
private final String UNKNOWN = "unknown";
|
||||
private final String UNKNOWN = "unknown";
|
||||
|
||||
/**
|
||||
* 判断是否ajax请求 spring ajax 返回含有 ResponseBody 或者 RestController注解
|
||||
* @param handlerMethod HandlerMethod
|
||||
* @return 是否ajax请求
|
||||
*/
|
||||
public boolean isBody(HandlerMethod handlerMethod) {
|
||||
ResponseBody responseBody = ClassUtils.getAnnotation(handlerMethod, ResponseBody.class);
|
||||
return responseBody != null;
|
||||
}
|
||||
/**
|
||||
* 判断是否ajax请求 spring ajax 返回含有 ResponseBody 或者 RestController注解
|
||||
*
|
||||
* @param handlerMethod HandlerMethod
|
||||
* @return 是否ajax请求
|
||||
*/
|
||||
public boolean isBody(HandlerMethod handlerMethod) {
|
||||
ResponseBody responseBody = ClassUtils.getAnnotation(handlerMethod, ResponseBody.class);
|
||||
return responseBody != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取cookie
|
||||
* @param name cookie name
|
||||
* @return cookie value
|
||||
*/
|
||||
public String getCookieVal(String name) {
|
||||
HttpServletRequest request = WebUtils.getRequest();
|
||||
Assert.notNull(request, "request from RequestContextHolder is null");
|
||||
return getCookieVal(request, name);
|
||||
}
|
||||
/**
|
||||
* 读取cookie
|
||||
*
|
||||
* @param name cookie name
|
||||
* @return cookie value
|
||||
*/
|
||||
public String getCookieVal(String name) {
|
||||
HttpServletRequest request = WebUtils.getRequest();
|
||||
Assert.notNull(request, "request from RequestContextHolder is null");
|
||||
return getCookieVal(request, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取cookie
|
||||
* @param request HttpServletRequest
|
||||
* @param name cookie name
|
||||
* @return cookie value
|
||||
*/
|
||||
public String getCookieVal(HttpServletRequest request, String name) {
|
||||
Cookie cookie = getCookie(request, name);
|
||||
return cookie != null ? cookie.getValue() : null;
|
||||
}
|
||||
/**
|
||||
* 读取cookie
|
||||
*
|
||||
* @param request HttpServletRequest
|
||||
* @param name cookie name
|
||||
* @return cookie value
|
||||
*/
|
||||
public String getCookieVal(HttpServletRequest request, String name) {
|
||||
Cookie cookie = getCookie(request, name);
|
||||
return cookie != null ? cookie.getValue() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除 某个指定的cookie
|
||||
* @param response HttpServletResponse
|
||||
* @param key cookie key
|
||||
*/
|
||||
public void removeCookie(HttpServletResponse response, String key) {
|
||||
setCookie(response, key, null, 0);
|
||||
}
|
||||
/**
|
||||
* 清除 某个指定的cookie
|
||||
*
|
||||
* @param response HttpServletResponse
|
||||
* @param key cookie key
|
||||
*/
|
||||
public void removeCookie(HttpServletResponse response, String key) {
|
||||
setCookie(response, key, null, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置cookie
|
||||
* @param response HttpServletResponse
|
||||
* @param name cookie name
|
||||
* @param value cookie value
|
||||
* @param maxAgeInSeconds maxage
|
||||
*/
|
||||
public void setCookie(HttpServletResponse response, String name, String value, int maxAgeInSeconds) {
|
||||
Cookie cookie = new Cookie(name, value);
|
||||
cookie.setPath("/");
|
||||
cookie.setMaxAge(maxAgeInSeconds);
|
||||
cookie.setHttpOnly(true);
|
||||
response.addCookie(cookie);
|
||||
}
|
||||
/**
|
||||
* 设置cookie
|
||||
*
|
||||
* @param response HttpServletResponse
|
||||
* @param name cookie name
|
||||
* @param value cookie value
|
||||
* @param maxAgeInSeconds maxage
|
||||
*/
|
||||
public void setCookie(HttpServletResponse response, String name, String value, int maxAgeInSeconds) {
|
||||
Cookie cookie = new Cookie(name, value);
|
||||
cookie.setPath("/");
|
||||
cookie.setMaxAge(maxAgeInSeconds);
|
||||
cookie.setHttpOnly(true);
|
||||
response.addCookie(cookie);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 HttpServletRequest
|
||||
* @return {HttpServletRequest}
|
||||
*/
|
||||
public HttpServletRequest getRequest() {
|
||||
try {
|
||||
RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
|
||||
return ((ServletRequestAttributes) requestAttributes).getRequest();
|
||||
}
|
||||
catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 获取 HttpServletRequest
|
||||
*
|
||||
* @return {HttpServletRequest}
|
||||
*/
|
||||
public HttpServletRequest getRequest() {
|
||||
try {
|
||||
RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
|
||||
return ((ServletRequestAttributes) requestAttributes).getRequest();
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 HttpServletResponse
|
||||
* @return {HttpServletResponse}
|
||||
*/
|
||||
public HttpServletResponse getResponse() {
|
||||
return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
|
||||
}
|
||||
/**
|
||||
* 获取 HttpServletResponse
|
||||
*
|
||||
* @return {HttpServletResponse}
|
||||
*/
|
||||
public HttpServletResponse getResponse() {
|
||||
return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回json
|
||||
* @param response HttpServletResponse
|
||||
* @param result 结果对象
|
||||
*/
|
||||
public void renderJson(HttpServletResponse response, Object result) {
|
||||
renderJson(response, result, MediaType.APPLICATION_JSON_VALUE);
|
||||
}
|
||||
/**
|
||||
* 返回json
|
||||
*
|
||||
* @param response HttpServletResponse
|
||||
* @param result 结果对象
|
||||
*/
|
||||
public void renderJson(HttpServletResponse response, Object result) {
|
||||
renderJson(response, result, MediaType.APPLICATION_JSON_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回json
|
||||
* @param response HttpServletResponse
|
||||
* @param result 结果对象
|
||||
* @param contentType contentType
|
||||
*/
|
||||
public void renderJson(HttpServletResponse response, Object result, String contentType) {
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
response.setContentType(contentType);
|
||||
try (PrintWriter out = response.getWriter()) {
|
||||
out.append(JSONUtil.toJsonStr(result));
|
||||
}
|
||||
catch (IOException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 返回json
|
||||
*
|
||||
* @param response HttpServletResponse
|
||||
* @param result 结果对象
|
||||
* @param contentType contentType
|
||||
*/
|
||||
public void renderJson(HttpServletResponse response, Object result, String contentType) {
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
response.setContentType(contentType);
|
||||
try (PrintWriter out = response.getWriter()) {
|
||||
out.append(JSONUtil.toJsonStr(result));
|
||||
} catch (IOException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取ip
|
||||
* @return {String}
|
||||
*/
|
||||
public String getIP() {
|
||||
return getIP(WebUtils.getRequest());
|
||||
}
|
||||
/**
|
||||
* 获取ip
|
||||
*
|
||||
* @return {String}
|
||||
*/
|
||||
public String getIP() {
|
||||
return getIP(WebUtils.getRequest());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取ip
|
||||
* @param request HttpServletRequest
|
||||
* @return {String}
|
||||
*/
|
||||
public String getIP(HttpServletRequest request) {
|
||||
Assert.notNull(request, "HttpServletRequest is null");
|
||||
String ip = request.getHeader("X-Requested-For");
|
||||
if (StrUtil.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("X-Forwarded-For");
|
||||
}
|
||||
if (StrUtil.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("Proxy-Client-IP");
|
||||
}
|
||||
if (StrUtil.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("WL-Proxy-Client-IP");
|
||||
}
|
||||
if (StrUtil.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("HTTP_CLIENT_IP");
|
||||
}
|
||||
if (StrUtil.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
|
||||
}
|
||||
if (StrUtil.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
|
||||
ip = request.getRemoteAddr();
|
||||
}
|
||||
return StrUtil.isBlank(ip) ? null : ip.split(",")[0];
|
||||
}
|
||||
/**
|
||||
* 获取ip
|
||||
*
|
||||
* @param request HttpServletRequest
|
||||
* @return {String}
|
||||
*/
|
||||
public String getIP(HttpServletRequest request) {
|
||||
Assert.notNull(request, "HttpServletRequest is null");
|
||||
String ip = request.getHeader("X-Requested-For");
|
||||
if (StrUtil.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("X-Forwarded-For");
|
||||
}
|
||||
if (StrUtil.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("Proxy-Client-IP");
|
||||
}
|
||||
if (StrUtil.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("WL-Proxy-Client-IP");
|
||||
}
|
||||
if (StrUtil.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("HTTP_CLIENT_IP");
|
||||
}
|
||||
if (StrUtil.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
|
||||
}
|
||||
if (StrUtil.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
|
||||
ip = request.getRemoteAddr();
|
||||
}
|
||||
return StrUtil.isBlank(ip) ? null : ip.split(",")[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析 client id
|
||||
* @param header
|
||||
* @param defVal
|
||||
* @return 如果解析失败返回默认值
|
||||
*/
|
||||
public String extractClientId(String header, final String defVal) {
|
||||
/**
|
||||
* 解析 client id
|
||||
*
|
||||
* @param header
|
||||
* @param defVal
|
||||
* @return 如果解析失败返回默认值
|
||||
*/
|
||||
public String extractClientId(String header, final String defVal) {
|
||||
|
||||
if (header == null || !header.startsWith(BASIC_)) {
|
||||
log.debug("请求头中client信息为空: {}", header);
|
||||
return defVal;
|
||||
}
|
||||
byte[] base64Token = header.substring(6).getBytes(StandardCharsets.UTF_8);
|
||||
byte[] decoded;
|
||||
try {
|
||||
decoded = Base64.decode(base64Token);
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
log.debug("Failed to decode basic authentication token: {}", header);
|
||||
return defVal;
|
||||
}
|
||||
if (header == null || !header.startsWith(BASIC_)) {
|
||||
log.debug("请求头中client信息为空: {}", header);
|
||||
return defVal;
|
||||
}
|
||||
byte[] base64Token = header.substring(6).getBytes(StandardCharsets.UTF_8);
|
||||
byte[] decoded;
|
||||
try {
|
||||
decoded = Base64.decode(base64Token);
|
||||
} catch (IllegalArgumentException e) {
|
||||
log.debug("Failed to decode basic authentication token: {}", header);
|
||||
return defVal;
|
||||
}
|
||||
|
||||
String token = new String(decoded, StandardCharsets.UTF_8);
|
||||
String token = new String(decoded, StandardCharsets.UTF_8);
|
||||
|
||||
int delim = token.indexOf(":");
|
||||
int delim = token.indexOf(":");
|
||||
|
||||
if (delim == -1) {
|
||||
log.debug("Invalid basic authentication token: {}", header);
|
||||
return defVal;
|
||||
}
|
||||
return token.substring(0, delim);
|
||||
}
|
||||
if (delim == -1) {
|
||||
log.debug("Invalid basic authentication token: {}", header);
|
||||
return defVal;
|
||||
}
|
||||
return token.substring(0, delim);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从请求头中解析 client id
|
||||
* @param header
|
||||
* @return
|
||||
*/
|
||||
public Optional<String> extractClientId(String header) {
|
||||
return Optional.ofNullable(extractClientId(header, null));
|
||||
}
|
||||
/**
|
||||
* 从请求头中解析 client id
|
||||
*
|
||||
* @param header
|
||||
* @return
|
||||
*/
|
||||
public Optional<String> extractClientId(String header) {
|
||||
return Optional.ofNullable(extractClientId(header, null));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 bearer 令牌
|
||||
*
|
||||
* @return {@link String }
|
||||
*/
|
||||
@SneakyThrows
|
||||
public String getToken() {
|
||||
if (Objects.isNull(WebUtils.getRequest())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 获取请求
|
||||
HttpServletRequest request = WebUtils.getRequest();
|
||||
// 获取Authorization头信息
|
||||
String authorizationHeader = request.getHeader(HttpHeaders.AUTHORIZATION);
|
||||
if (authorizationHeader != null && StrUtil.startWithAnyIgnoreCase(authorizationHeader, "Bearer ")) {
|
||||
// 返回去掉"Bearer "前缀的Token
|
||||
return authorizationHeader.substring(7);
|
||||
} else {
|
||||
// 处理Authorization头信息为空或格式不正确的情况
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -28,3 +28,10 @@ liteflow:
|
||||
# 关闭连表插件的banner
|
||||
mybatis-plus-join:
|
||||
banner: false
|
||||
|
||||
# sa-token 配置
|
||||
sa-token:
|
||||
is-print: false # 不输出 banner
|
||||
token-name: pig # token 存储的前缀
|
||||
is-concurrent: true # 是否允许同时在线
|
||||
is-share: false # 是否允许复用token (同一账号同时登录的情况)
|
||||
Reference in new issue
Block a user