No SecurityManager accessible to the calling code, either bound to the

强制登出所有用户,每次升级之前强制用户重新登录No SecurityManager accessible to the calling code, either bound to the org.ap

原创

君子志邦2022-05-17 15:03:39博主文章分类:2021年工作©著作权

文章标签强制登出所有用户升级前提出登录踢出登录用户springjava文章分类Spark大数据阅读数227

 

 

 

解决办法:在 ShiroConfig.java 中的方法

public SecurityManager securityManager(UserRealm userRealm, SpringSessionValidationScheduler springSessionValidationScheduler)中添加:ThreadContext.bind(securityManager);

错误信息:

异常信息:
2021-01-0709:39:16.299|ERROR|main|212|c.h.j.rpc.t2.util.ServiceDefinitionUtil :解析接口方法异常: method:queryTagsByCategory
2021-01-0709:39:16.332|ERROR|main|212|c.h.j.rpc.t2.util.ServiceDefinitionUtil :解析接口方法异常: method:queryTagsByTagValue
2021-01-0709:39:16.345|ERROR|main|212|c.h.j.rpc.t2.util.ServiceDefinitionUtil :解析接口方法异常: method:registerTags
2021-01-0709:39:51.590|ERROR|main|212|c.h.j.rpc.t2.util.ServiceDefinitionUtil :解析接口方法异常: method:queryConditionList
2021-01-0709:40:24.033|ERROR|main|845|o.s.boot.SpringApplication              :Applicationrunfailed
java.lang.IllegalStateException: FailedtoexecuteCommandLineRunner
atorg.springframework.boot.SpringApplication.callRunner(SpringApplication.java:803)
atorg.springframework.boot.SpringApplication.callRunners(SpringApplication.java:784)
atorg.springframework.boot.SpringApplication.run(SpringApplication.java:338)
atorg.gil.three.admin.ThreeAdminApplication.main(ThreeAdminApplication.java:35)
Causedby: org.apache.shiro.UnavailableSecurityManagerException: NoSecurityManageraccessibletothecallingcode, eitherboundtotheorg.apache.shiro.util.ThreadContextorasavmstaticsingleton.  Thisisaninvalidapplicationconfiguration.
atorg.apache.shiro.SecurityUtils.getSecurityManager(SecurityUtils.java:123)
atorg.gil.three.admin.util.ShiroUtil.kickOutAllUsers(ShiroUtil.java:109)
atorg.gil.three.admin.runner.RedisFlushCommandLineRunner.run(RedisFlushCommandLineRunner.java:42)
atorg.springframework.boot.SpringApplication.callRunner(SpringApplication.java:800)
  ... 3commonframesomitted
java.lang.IllegalStateException: FailedtoexecuteCommandLineRunner
atorg.springframework.boot.SpringApplication.callRunner(SpringApplication.java:803)
atorg.springframework.boot.SpringApplication.callRunners(SpringApplication.java:784)
atorg.springframework.boot.SpringApplication.run(SpringApplication.java:338)
atorg.gil.three.admin.ThreeAdminApplication.main(ThreeAdminApplication.java:35)
Causedby: org.apache.shiro.UnavailableSecurityManagerException: NoSecurityManageraccessibletothecallingcode, eitherboundtotheorg.apache.shiro.util.ThreadContextorasavmstaticsingleton.  Thisisaninvalidapplicationconfiguration.
atorg.apache.shiro.SecurityUtils.getSecurityManager(SecurityUtils.java:123)
atorg.gil.three.admin.util.ShiroUtil.kickOutAllUsers(ShiroUtil.java:109)
atorg.gil.three.admin.runner.RedisFlushCommandLineRunner.run(RedisFlushCommandLineRunner.java:42)
atorg.springframework.boot.SpringApplication.callRunner(SpringApplication.java:800)
  ... 3more
DisconnectedfromthetargetVM, address: '127.0.0.1:12507', transport: 'socket'

Processfinishedwithexitcode-1
format,png

文字描述:

Caused by: org.apache.shiro.UnavailableSecurityManagerException: No SecurityManager accessible to the calling code, either bound to the org.apache.shiro.util.ThreadContext or as a vm static singleton.  This is an invalid application configuration.
    at org.apache.shiro.SecurityUtils.getSecurityManager(SecurityUtils.java:123)
    at org.gil.three.admin.util.ShiroUtil.kickOutAllUsers(ShiroUtil.java:109)
    at org.gil.three.admin.runner.RedisFlushCommandLineRunner.run(RedisFlushCommandLineRunner.java:42)
    at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:800)
    ... 3 common frames omitted

主要是类的获取有问题,静态方法没有实例化类,所以获取有问题

importjava.util.Collection;
importjava.util.Objects;

importorg.apache.shiro.SecurityUtils;
importorg.apache.shiro.authc.Authenticator;
importorg.apache.shiro.authc.LogoutAware;
importorg.apache.shiro.session.Session;
importorg.apache.shiro.subject.SimplePrincipalCollection;
importorg.apache.shiro.subject.support.DefaultSubjectContext;
importorg.apache.shiro.web.mgt.DefaultWebSecurityManager;
importorg.crazycake.shiro.RedisSessionDAO;
importorg.gil.three.admin.model.vo.SessionUser;

publicclassShiroUtil {

privatestaticRedisSessionDAOredisSessionDAO=SpringUtil
        .getBean(RedisSessionDAO.class);

privateShiroUtil() {
    }

/**
* 获取指定用户名的Session
* @param username
* @return
*/
privatestaticSessiongetSessionByUsername(Stringusername) {
Collection<Session>sessions=redisSessionDAO.getActiveSessions();
SessionUseruser;
Objectattribute;
for (Sessionsession : sessions) {
attribute=session
                .getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
if (attribute==null) {
continue;
            }
user= (SessionUser) ((SimplePrincipalCollection) attribute)
                .getPrimaryPrincipal();
if (user==null) {
continue;
            }
if (Objects.equals(user.getUserName(), username)) {
returnsession;
            }
        }
returnnull;
    }

/**
* 删除用户缓存信息
* @param username 用户名
* @param isRemoveSession 是否删除session,删除后用户需重新登录
*/
publicstaticvoidkickOutUser(Stringusername, booleanisRemoveSession) {
Sessionsession=getSessionByUsername(username);
if (session==null) {
return;
        }

Objectattribute=session
            .getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
if (attribute==null) {
return;
        }

SessionUseruser= (SessionUser) ((SimplePrincipalCollection) attribute)
            .getPrimaryPrincipal();
if (!username.equals(user.getUserName())) {
return;
        }

// 删除session
if (isRemoveSession) {
redisSessionDAO.delete(session);
        }
DefaultWebSecurityManagersecurityManager= (DefaultWebSecurityManager) SecurityUtils
            .getSecurityManager();
Authenticatorauthc=securityManager.getAuthenticator();
// 删除cache,在访问受限接口时会重新授权
        ((LogoutAware) authc).onLogout((SimplePrincipalCollection) attribute);
    }

}

 

解决办法:

 

@Autowired
private AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor;

DefaultWebSecurityManager securityManager = (DefaultWebSecurityManager) authorizationAttributeSourceAdvisor.getSecurityManager();
  Authenticator authc = securityManager.getAuthenticator();

authorizationAttributeSourceAdvisor在shiroconfig配置的里面声明bean,这里注入,然后直接就可以获取到了

修改之后的实现类:

登录后复制

importlombok.extern.slf4j.Slf4j;
importorg.apache.shiro.SecurityUtils;
importorg.apache.shiro.authc.Authenticator;
importorg.apache.shiro.authc.LogoutAware;
importorg.apache.shiro.session.Session;
importorg.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
importorg.apache.shiro.subject.SimplePrincipalCollection;
importorg.apache.shiro.subject.support.DefaultSubjectContext;
importorg.apache.shiro.web.mgt.DefaultWebSecurityManager;
importorg.gil.three.admin.config.shiro.ShiroResdisSessionDAO;
importorg.gil.three.admin.model.vo.SessionUser;
importorg.springframework.beans.factory.annotation.Autowired;
importorg.springframework.stereotype.Component;

importjava.util.Collection;
importjava.util.Objects;

@Component
@Slf4j
publicclassShiroUtil {

@Autowired
privateShiroResdisSessionDAOshiroResdisSessionDAO;

@Autowired
privateAuthorizationAttributeSourceAdvisorauthorizationAttributeSourceAdvisor;

privateShiroUtil() {
    }

/**
* 获取指定用户名的Session
*
* @param username
* @return
*/
privateSessiongetSessionByUsername(Stringusername) {
Collection<Session>sessions=shiroResdisSessionDAO.getActiveSessions();
SessionUseruser;
Objectattribute;
for (Sessionsession : sessions) {
attribute=session
                    .getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
if (attribute==null) {
continue;
            }
user= (SessionUser) ((SimplePrincipalCollection) attribute)
                    .getPrimaryPrincipal();
if (user==null) {
continue;
            }
if (Objects.equals(user.getUserName(), username)) {
returnsession;
            }
        }
returnnull;
    }

/**
* 删除用户缓存信息
*
* @param username        用户名
* @param isRemoveSession 是否删除session,删除后用户需重新登录
*/
publicvoidkickOutUser(Stringusername, booleanisRemoveSession) {
Sessionsession=getSessionByUsername(username);
if (session==null) {
return;
        }

Objectattribute=session
                .getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
if (attribute==null) {
return;
        }

SessionUseruser= (SessionUser) ((SimplePrincipalCollection) attribute)
                .getPrimaryPrincipal();
if (!username.equals(user.getUserName())) {
return;
        }

// 删除session
if (isRemoveSession) {
shiroResdisSessionDAO.delete(session);
        }
DefaultWebSecurityManagersecurityManager= (DefaultWebSecurityManager) SecurityUtils
                .getSecurityManager();
Authenticatorauthc=securityManager.getAuthenticator();
// 删除cache,在访问受限接口时会重新授权
        ((LogoutAware) authc).onLogout((SimplePrincipalCollection) attribute);
    }

publicvoidkickOutAllUsers() {
Collection<Session>sessions=shiroResdisSessionDAO.getActiveSessions();
SessionUseruser;
Objectattribute;
for (Sessionsession : sessions) {
attribute=session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
if (attribute==null) {
continue;
            }
user= (SessionUser) ((SimplePrincipalCollection) attribute).getPrimaryPrincipal();
if (user==null) {
continue;
            }
shiroResdisSessionDAO.delete(session);
DefaultWebSecurityManagersecurityManager= (DefaultWebSecurityManager) authorizationAttributeSourceAdvisor.getSecurityManager();
Authenticatorauthc=securityManager.getAuthenticator();

// 删除cache,在访问受限接口时会重新授权
            ((LogoutAware) authc).onLogout((SimplePrincipalCollection) attribute);
log.error("用户强制登出,用户名:{},用户id:{}",user.getRealName(),user.getId());
        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值