• Spring Security11、登录用户管理


    在后台管理中,我们常常需要查看在线的用户,然后管理用户,比如踢出用户等操作。

    在 spring security 同样也可以做到,我们只需要在 HttpSecurity 中配置sessionRegistry,然后就可以在容器中注入SessionRegistry,调用其方法来实现。

    一、注入SessionRegistry

    SecurityConfig.java
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            ...(省略其他配置)...
            // 配置Session注册器
            .sessionRegistry(sessionRegistry());
    }
        
    /***
     * 注入Session注册器
     * 可使用该类获取在线的全部用户
     */
    @Bean
    public SessionRegistry sessionRegistry() {
        return new SessionRegistryImpl();
    }
    

    二、使用SessionRegistry获取在线用户+踢出用户

    package com.miaopasi.securitydemo.controller;
    
    import cn.hutool.core.lang.Console;
    import cn.hutool.core.lang.Dict;
    import cn.hutool.core.util.RandomUtil;
    import cn.hutool.core.util.StrUtil;
    import com.miaopasi.securitydemo.config.security.SysUser;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.mail.javamail.JavaMailSender;
    import org.springframework.mail.javamail.MimeMessageHelper;
    import org.springframework.security.core.Authentication;
    import org.springframework.security.core.context.SecurityContextHolder;
    import org.springframework.security.core.session.SessionInformation;
    import org.springframework.security.core.session.SessionRegistry;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    
    import javax.mail.MessagingException;
    import javax.mail.internet.MimeMessage;
    import javax.servlet.http.HttpServletRequest;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Objects;
    import java.util.stream.Collectors;
    
    /**
     * 测试工具类
     *
     * @author lixin
     */
    @RestController
    public class TestController {
        private final SessionRegistry sessionRegistry;
    
    
        @Autowired
        public TestController(SessionRegistry sessionRegistry) {
            this.sessionRegistry = sessionRegistry;
        }
    
        /*** 获取全部在线用户 **/
        @GetMapping("/loginUsers")
        public List<Object> loginUsers() {
            return sessionRegistry.getAllPrincipals();
        }
    
        /*** 踢出指定用户 **/
        @PostMapping("kickOut")
        public Integer kickOutUser(@RequestParam(name = "username") String username) {
            // 1.在全部的登录用户中或者到指定对象
            final List<Object> allPrincipals = sessionRegistry.getAllPrincipals();
            final List<Object> collect = allPrincipals.stream().filter((item) -> Objects.equals(username, ((SysUser) item).getUsername())).collect(Collectors.toList());
            // 2.获取指定对象全部的Session(多登录)
            List<SessionInformation> sessions = new ArrayList<>();
            collect.forEach((item) -> sessions.addAll(sessionRegistry.getAllSessions(item, false)));
            // 3.设置Session过期
            sessions.forEach((item)->{
                // 立即过期
                item.expireNow();
                // 移除Session
                sessionRegistry.removeSessionInformation(item.getSessionId());
            });
            // 4.返回清除的记录数
            return sessions.size();
        }
    }
    

    三、测试接口

    • 登录用户 user1、user2、user3,然后调用接口 /loginUsers
    [
        {
            "id": 1,
            "gmtCreate": "2021-08-07T11:18:21.524+0000",
            "gmtModified": null,
            "isDelete": false,
            "operator": "管理员",
            "sort": 0,
            "version": null,
            "username": "user1",
            "password": null,
            "status": 0,
            "remarks": "测试用户1",
            "authorities": [
                {
                    "authority": "guest"
                }
            ],
            "enabled": true,
            "accountNonExpired": true,
            "accountNonLocked": true,
            "credentialsNonExpired": true
        },
        {
            "id": 2,
            "gmtCreate": "2021-08-07T14:13:18.784+0000",
            "gmtModified": null,
            "isDelete": false,
            "operator": "管理员",
            "sort": 0,
            "version": null,
            "username": "user2",
            "password": null,
            "status": 0,
            "remarks": "测试用户2",
            "authorities": [
                {
                    "authority": "guest"
                }
            ],
            "enabled": true,
            "accountNonExpired": true,
            "accountNonLocked": true,
            "credentialsNonExpired": true
        },
        {
            "id": 3,
            "gmtCreate": "2021-08-07T14:13:38.176+0000",
            "gmtModified": null,
            "isDelete": false,
            "operator": "管理员",
            "sort": 0,
            "version": null,
            "username": "user3",
            "password": null,
            "status": 0,
            "remarks": "测试用户3",
            "authorities": [
                {
                    "authority": "guest"
                }
            ],
            "enabled": true,
            "accountNonExpired": true,
            "accountNonLocked": true,
            "credentialsNonExpired": true
        }
    ]
    
    • 我们现在调用接口/kickOut踢出登录用user2
    POST http://127.0.0.1:8080/kickOut
    
    HTTP/1.1 200 
    Vary: Origin
    Vary: Access-Control-Request-Method
    Vary: Access-Control-Request-Headers
    X-Content-Type-Options: nosniff
    X-XSS-Protection: 1; mode=block
    Cache-Control: no-cache, no-store, max-age=0, must-revalidate
    Pragma: no-cache
    Expires: 0
    X-Frame-Options: DENY
    Content-Type: application/json
    Transfer-Encoding: chunked
    Date: Sat, 07 Aug 2021 14:17:28 GMT
    Keep-Alive: timeout=60
    Connection: keep-alive
    
    1
    
    Response code: 200; Time: 24ms; Content length: 1 bytes
    
    • 然后我们在登录了user2的浏览器上刷新
    {
        "msg": "你的账号已在其他地方登录",
        "code": 1000
    }
    
    原创内容,如果你觉得文章还可以的话,不妨点个赞支持一下!转载请注明出处。
  • 相关阅读:
    Jmeter实现dubbo接口压测案例
    Jmeter性能测试报告扩展
    Jmeter3.2源码编译环境搭建
    JMeter中添加dubbo相关插件异常问题解决
    JMeter3.0启动日志报错WARN
    JMeter关联的几种方式总结案例
    JMeter调试参数是否取值正确,调试正则提取的结果(log.info|log.error|print)
    jdk1.7更新visualvm插件
    如何自定义 maven中的archetype
    java提高篇(四)-----理解java的三大特性之多态
  • 原文地址:https://www.cnblogs.com/lixingwu/p/15113568.html
Copyright © 2020-2023  润新知