• 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
    }
    
    原创内容,如果你觉得文章还可以的话,不妨点个赞支持一下!转载请注明出处。
  • 相关阅读:
    echart自定义浮窗 增加点击事件
    原生js学习 选择dom
    GOjs版本2.0去除水印
    js 作用域
    javaScript的原型模式
    JavaScript的基本包装类型说明
    原生js 函数 callee属性
    Vue学习-基本指令
    js函数
    Kubernetes(一):云计算发展历程
  • 原文地址:https://www.cnblogs.com/lixingwu/p/15113568.html
Copyright © 2020-2023  润新知