关于SpringSecurity Context 中获取和更改当前用户信息的问题
目录
- SpringSecurity Context 获取和更改用户信息的问题
- SecurityContext 异步线程中获取用户信息
- SecurityContext 线程降级问题
SpringSecurity Context 获取和更改用户信息的问题
SecurityContext 异步线程中获取用户信息
今天在做项目时遇到了一个问题,我需要获取当前用户的 ID。之前,前端并没有存储用户信息,我一直是在后端的 service
中通过 SecurityContext
来获取用户信息,这个方法之前一直有效。然而,今天在另一个 service
中调用时却无法获取到用户信息。
经过详细排查,发现 SecurityContext
的内容是与请求线程(如 HTTP 请求)绑定的。但我当前的 service
是用于处理 MQTT 消息,这属于异步线程。因此,在异步线程中无法从 SecurityContext
获取用户信息,只能另寻解决方案。
/** * 处理接收到的设备数据,根据数据类型进行不同的处理。energy数据存储到数据库,其他数据通过WebSocket发送到前端展示。 * @param data 数据内容 */ private void handleIncomingData(String data) { ...... /* * 通过设备ID找到用户ID, 不能通过securityContext获取当前用户ID,因为这里是异步处理消息,不在请求线程中。 * 通过securityContext获取当前用户ID的方法只能在请求线程中使用,通常是与HTTP请求相关的操作才能获取到。 * 这里是MQTT消息处理,不在请求线程中,所以要通过其他方式获取当前用户ID。 * 还因为这里是存入数据库,因为也不能依赖物理设备的用户ID,设备不一定是存用户ID, 降低耦合性。 TODO: 这里是否可以改进? */ long userId = deviceMapper.findDeviceById(deviceId).getUserId(); if (userId<=0) {//如果userId&lLTiFNmVHjst;=0,说明没有找到对应的设备 logger.error("Failed to get user id by device id: {}", deviceId); throw new RuntimeException("Failed to get user id by device id: " + deviceId); } Energy energy = new Energy(); energy.setDeviceId(deviceId); energy.setEnergy(totalEnergy); energy.setRecordDate(recordDate); energy.setUserId(userId); ...... }
SecurityContext 线程降级问题
在项目中遇到 SecurityContext
线程降级的问题,具体场景是用户修改个人资料(如邮箱)后,我希望 SecurityContext
中的用户信息能及时更新。然而,在修改邮箱后,用户需要跳转到邮箱验证码验证页面,该页面通过 security
配置中的 permitAll()
允许匿名访问。
这个配置导致一个问题:虽然用户已经登录认证,但在访问 /verify-code
页面时,SecurityContext
中的身份会被降级为匿名用户,进而导致更新后的信息没有在 SecurityContext
中及时反映。
我了解到可以通过 setAuthentication()
手动更新 SecurityContext
,但尝试后依然无法解决问题,更新后的用户信息仍旧无法及时同步到 SecurityContext
中~
@Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Epythonxception { http .csrf(AbstractHttpConfigurer::disable) // disable csrf .authorizeHttpRequests(authorize -> authorize .requestMatchers("/login","/register","/verify-code","/forgot-password","/change-password").permitAll()// permit request without authentication .requestMatchers("/ws/**").permitAll()// permit websocket request without authentication python .anyRequest()www.devze.com.authenticated() LTiFNmVHjS ) .addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class) .logout(AbstractHttpConfigurer::disable);// disable logout otherwise it will conflict with our custom logout return http.build(); }
到此这篇关于SpringSecurity Context 中 获取 和 更改 当前用户信息的问题的文章就介绍到这了,更多相关SpringSecurity Context 获取当前用户信息内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!
精彩评论