当前位置:网站首页>websocket校验token:使用threadlocal存放和获取当前登录用户
websocket校验token:使用threadlocal存放和获取当前登录用户
2022-08-10 18:15:00 【march of Time】
都知道threadlocal可以用于线程之间的变量隔离,在登录时中它可以放入当前用户,之后再用于获取当前登录用户,下面是一个使用实例。
用户实体类:(jpa框架)
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("sys_user")
public class SysUser extends SuperEntity {
private static final long serialVersionUID = -5886012896705137070L;
private String username;
private String password;
private String nickname;
private String headImgUrl;
private String mobile;
private Integer sex;
private Boolean enabled;
private String type;
private String openId;
@TableLogic
private boolean isDel;
}
threadlocal类:
public class LoginUserContextHolder {
private static final ThreadLocal<SysUser> CONTEXT = new TransmittableThreadLocal<>();
public static void setUser(SysUser user) {
CONTEXT.set(user);
}
public static SysUser getUser() {
return CONTEXT.get();
}
public static void clear() {
CONTEXT.remove();
}
}
防止用户到threadlocal中:
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.exceptions.InvalidTokenException;
import org.springframework.security.oauth2.common.exceptions.UnapprovedClientAuthenticationException;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.TokenStore;
import javax.servlet.http.HttpServletRequest;
import java.nio.charset.StandardCharsets;
import java.util.*;
public class AuthUtils {
/** * 校验accessToken */
public static SysUser checkAccessToken(HttpServletRequest request) {
String accessToken = extractToken(request);
return checkAccessToken(accessToken);
}
public static SysUser checkAccessToken(String accessTokenValue) {
TokenStore tokenStore = SpringUtil.getBean(TokenStore.class);
OAuth2AccessToken accessToken = tokenStore.readAccessToken(accessTokenValue);
if (accessToken == null || accessToken.getValue() == null) {
throw new InvalidTokenException("Invalid access token: " + accessTokenValue);
} else if (accessToken.isExpired()) {
tokenStore.removeAccessToken(accessToken);
throw new InvalidTokenException("Access token expired: " + accessTokenValue);
}
OAuth2Authentication result = tokenStore.readAuthentication(accessToken);
if (result == null) {
throw new InvalidTokenException("Invalid access token: " + accessTokenValue);
}
return setContext(result);
}
/** * 用户信息赋值 context 对象 */
public static SysUser setContext(Authentication authentication) {
SecurityContextHolder.getContext().setAuthentication(authentication);
SysUser user = getUser(authentication);
LoginUserContextHolder.setUser(user);
return user;
}
/** * *从header 请求中的clientId:clientSecret */
public static String[] extractClient(HttpServletRequest request) {
String header = request.getHeader("Authorization");
if (header == null || !header.startsWith(BASIC_)) {
throw new UnapprovedClientAuthenticationException("请求头中client信息为空");
}
return extractHeaderClient(header);
}
/** * 从header 请求中的clientId:clientSecret * * @param header header中的参数 */
public static String[] extractHeaderClient(String header) {
byte[] base64Client = header.substring(BASIC_.length()).getBytes(StandardCharsets.UTF_8);
byte[] decoded = Base64.getDecoder().decode(base64Client);
String clientStr = new String(decoded, StandardCharsets.UTF_8);
String[] clientArr = clientStr.split(":");
if (clientArr.length != 2) {
throw new RuntimeException("Invalid basic authentication token");
}
return clientArr;
}
获取当前登录人:
/** * 通过 LoginUserContextHolder 获取当前登录人 */
@GetMapping("/test/auth2")
public String auth() {
return "auth2:" + LoginUserContextHolder.getUser().getUsername();
}
websocket鉴权:
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.websocket.server.ServerEndpointConfig;
public class WcAuthConfigurator extends ServerEndpointConfig.Configurator {
//checkOrigin:校验token
@Override
public boolean checkOrigin(String originHeaderValue) {
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
try {
//检查token有效性
AuthUtils.checkAccessToken(servletRequestAttributes.getRequest());
} catch (Exception e) {
log.error("WebSocket-auth-error", e);
return false;
}
return super.checkOrigin(originHeaderValue);
}
}
在AuthUtils.checkAccessToken方法内部最终执行了threadelocal的put方法
使用WcAuthConfigurator :
//@ServerEndpoint:
主要是将目前的类定义成一个websocket服务器端, 注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端,在这里配置configurator属性为刚刚写的配置类
@Slf4j
@Component
@ServerEndpoint(value = "/websocket/test", configurator = WcAuthConfigurator.class)
public class TestWebSocketController {
@OnOpen
public void onOpen(Session session) throws IOException {
session.getBasicRemote().sendText("TestWebSocketController-ok");
}
}
边栏推荐
- pyspark列合并为一行
- 【FAQ】【Push Kit】推送服务,回执配置一直报错、回执过期修改、怎么删除配置的回执
- 「POJ 3666」Making the Grade 题解(两种做法)
- FlexSim仿真软件入门笔记:基本操作、快捷键
- 【接入指南 之 直接接入】手把手教你快速上手接入HONOR Connect平台(下)
- HarmonyOS自动化测试框架—Hypium
- 【FAQ】OpenHarmony与HarmonyOS的有什么区别?
- flex使用align-content无效
- 【HMS core】【FAQ】AR Engine、Analytics Kit、Video Editor Kit、Image Kit、Map Kit典型问题合集2
- 接口测试进阶接口脚本使用—apipost(预/后执行脚本)
猜你喜欢

【HMS core】【FAQ】AR Engine、Analytics Kit、Video Editor Kit、Image Kit、Map Kit典型问题合集2

2022-08-09 Study Notes day32-IO Stream

直播回顾|多云时代,如何建设企业级云管理平台?(附建设指南下载)

高手问答第 290 期 —— SaaS产品经理从菜鸟到专家

Flexsim 发生器设置label和颜色

「业务架构」业务能力的热图是什么,有啥用?

【图像分割】基于元胞自动机实现图像分割附matlab代码

Making Pre-trained Language Models Better Few-Shot Learners

Interface test advanced interface script using -apipost (pre/post execution script)

老板加薪!看我做的WPF Loading!!!
随机推荐
StoneDB 文档捉虫活动第一季
【HMS core】【FAQ】Account Kit、push Kit典型问题合集1
IoU、GIoU、DIoU、CIoU四种损失函数总结
#yyds干货盘点# 面试必刷TOP101:二分查找-I
Keil5退出仿真调试卡死的解决办法
【HMS core】【FAQ】AR Engine、Analytics Kit、Video Editor Kit、Image Kit、Map Kit典型问题合集2
requires ‘angle‘ attribute to be a multiple of 45
机器人控制器编程整理汇总-辞旧迎新-
兼具外观、性能、屏幕!华硕灵耀X 14火热抢购中
【FAQ】【Push Kit】推送服务,回执配置一直报错、回执过期修改、怎么删除配置的回执
img转base64
FlexSim仿真软件入门笔记:基本操作、快捷键
php7中使用“??”运算符
pyspark列合并为一行
set和map使用讲解
微信小程序富文本标签rich-text
机器人控制器编程实践指导书旧版-实践五 数字舵机(执行器)
【深度学习21天学习挑战赛】4、初尝循环神经网络(RNN)——股票预测
三星Galaxy Watch5产品图片流出 非Pro表款亦有蓝宝石加持
【快应用】实现自定义导航栏组件