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

拼搏现实的明天。 2023-01-03 04:13 113阅读 0赞

异常信息:

  1. 2021-01-07 09:39:16.299|ERROR|main|212|c.h.j.rpc.t2.util.ServiceDefinitionUtil :解析接口方法异常: method:queryTagsByCategory
  2. 2021-01-07 09:39:16.332|ERROR|main|212|c.h.j.rpc.t2.util.ServiceDefinitionUtil :解析接口方法异常: method:queryTagsByTagValue
  3. 2021-01-07 09:39:16.345|ERROR|main|212|c.h.j.rpc.t2.util.ServiceDefinitionUtil :解析接口方法异常: method:registerTags
  4. 2021-01-07 09:39:51.590|ERROR|main|212|c.h.j.rpc.t2.util.ServiceDefinitionUtil :解析接口方法异常: method:queryConditionList
  5. 2021-01-07 09:40:24.033|ERROR|main|845|o.s.boot.SpringApplication :Application run failed
  6. java.lang.IllegalStateException: Failed to execute CommandLineRunner
  7. at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:803)
  8. at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:784)
  9. at org.springframework.boot.SpringApplication.run(SpringApplication.java:338)
  10. at org.gil.three.admin.ThreeAdminApplication.main(ThreeAdminApplication.java:35)
  11. 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.
  12. at org.apache.shiro.SecurityUtils.getSecurityManager(SecurityUtils.java:123)
  13. at org.gil.three.admin.util.ShiroUtil.kickOutAllUsers(ShiroUtil.java:109)
  14. at org.gil.three.admin.runner.RedisFlushCommandLineRunner.run(RedisFlushCommandLineRunner.java:42)
  15. at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:800)
  16. ... 3 common frames omitted
  17. java.lang.IllegalStateException: Failed to execute CommandLineRunner
  18. at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:803)
  19. at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:784)
  20. at org.springframework.boot.SpringApplication.run(SpringApplication.java:338)
  21. at org.gil.three.admin.ThreeAdminApplication.main(ThreeAdminApplication.java:35)
  22. 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.
  23. at org.apache.shiro.SecurityUtils.getSecurityManager(SecurityUtils.java:123)
  24. at org.gil.three.admin.util.ShiroUtil.kickOutAllUsers(ShiroUtil.java:109)
  25. at org.gil.three.admin.runner.RedisFlushCommandLineRunner.run(RedisFlushCommandLineRunner.java:42)
  26. at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:800)
  27. ... 3 more
  28. Disconnected from the target VM, address: '127.0.0.1:12507', transport: 'socket'
  29. Process finished with exit code -1

错误信息:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTE0ODgwMDk_size_16_color_FFFFFF_t_70

文字描述:

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

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

  1. import java.util.Collection;
  2. import java.util.Objects;
  3. import org.apache.shiro.SecurityUtils;
  4. import org.apache.shiro.authc.Authenticator;
  5. import org.apache.shiro.authc.LogoutAware;
  6. import org.apache.shiro.session.Session;
  7. import org.apache.shiro.subject.SimplePrincipalCollection;
  8. import org.apache.shiro.subject.support.DefaultSubjectContext;
  9. import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
  10. import org.crazycake.shiro.RedisSessionDAO;
  11. import org.gil.three.admin.model.vo.SessionUser;
  12. public class ShiroUtil {
  13. private static RedisSessionDAO redisSessionDAO = SpringUtil
  14. .getBean(RedisSessionDAO.class);
  15. private ShiroUtil() {
  16. }
  17. /**
  18. * 获取指定用户名的Session
  19. * @param username
  20. * @return
  21. */
  22. private static Session getSessionByUsername(String username) {
  23. Collection<Session> sessions = redisSessionDAO.getActiveSessions();
  24. SessionUser user;
  25. Object attribute;
  26. for (Session session : sessions) {
  27. attribute = session
  28. .getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
  29. if (attribute == null) {
  30. continue;
  31. }
  32. user = (SessionUser) ((SimplePrincipalCollection) attribute)
  33. .getPrimaryPrincipal();
  34. if (user == null) {
  35. continue;
  36. }
  37. if (Objects.equals(user.getUserName(), username)) {
  38. return session;
  39. }
  40. }
  41. return null;
  42. }
  43. /**
  44. * 删除用户缓存信息
  45. * @param username 用户名
  46. * @param isRemoveSession 是否删除session,删除后用户需重新登录
  47. */
  48. public static void kickOutUser(String username, boolean isRemoveSession) {
  49. Session session = getSessionByUsername(username);
  50. if (session == null) {
  51. return;
  52. }
  53. Object attribute = session
  54. .getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
  55. if (attribute == null) {
  56. return;
  57. }
  58. SessionUser user = (SessionUser) ((SimplePrincipalCollection) attribute)
  59. .getPrimaryPrincipal();
  60. if (!username.equals(user.getUserName())) {
  61. return;
  62. }
  63. // 删除session
  64. if (isRemoveSession) {
  65. redisSessionDAO.delete(session);
  66. }
  67. DefaultWebSecurityManager securityManager = (DefaultWebSecurityManager) SecurityUtils
  68. .getSecurityManager();
  69. Authenticator authc = securityManager.getAuthenticator();
  70. // 删除cache,在访问受限接口时会重新授权
  71. ((LogoutAware) authc).onLogout((SimplePrincipalCollection) attribute);
  72. }
  73. }

解决办法:

  1. @Autowired
  2. private AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor;
  3. DefaultWebSecurityManager securityManager = (DefaultWebSecurityManager) authorizationAttributeSourceAdvisor.getSecurityManager();
  4. Authenticator authc = securityManager.getAuthenticator();

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

修改之后的实现类:

  1. import lombok.extern.slf4j.Slf4j;
  2. import org.apache.shiro.SecurityUtils;
  3. import org.apache.shiro.authc.Authenticator;
  4. import org.apache.shiro.authc.LogoutAware;
  5. import org.apache.shiro.session.Session;
  6. import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
  7. import org.apache.shiro.subject.SimplePrincipalCollection;
  8. import org.apache.shiro.subject.support.DefaultSubjectContext;
  9. import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
  10. import org.gil.three.admin.config.shiro.ShiroResdisSessionDAO;
  11. import org.gil.three.admin.model.vo.SessionUser;
  12. import org.springframework.beans.factory.annotation.Autowired;
  13. import org.springframework.stereotype.Component;
  14. import java.util.Collection;
  15. import java.util.Objects;
  16. @Component
  17. @Slf4j
  18. public class ShiroUtil {
  19. @Autowired
  20. private ShiroResdisSessionDAO shiroResdisSessionDAO;
  21. @Autowired
  22. private AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor;
  23. private ShiroUtil() {
  24. }
  25. /**
  26. * 获取指定用户名的Session
  27. *
  28. * @param username
  29. * @return
  30. */
  31. private Session getSessionByUsername(String username) {
  32. Collection<Session> sessions = shiroResdisSessionDAO.getActiveSessions();
  33. SessionUser user;
  34. Object attribute;
  35. for (Session session : sessions) {
  36. attribute = session
  37. .getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
  38. if (attribute == null) {
  39. continue;
  40. }
  41. user = (SessionUser) ((SimplePrincipalCollection) attribute)
  42. .getPrimaryPrincipal();
  43. if (user == null) {
  44. continue;
  45. }
  46. if (Objects.equals(user.getUserName(), username)) {
  47. return session;
  48. }
  49. }
  50. return null;
  51. }
  52. /**
  53. * 删除用户缓存信息
  54. *
  55. * @param username 用户名
  56. * @param isRemoveSession 是否删除session,删除后用户需重新登录
  57. */
  58. public void kickOutUser(String username, boolean isRemoveSession) {
  59. Session session = getSessionByUsername(username);
  60. if (session == null) {
  61. return;
  62. }
  63. Object attribute = session
  64. .getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
  65. if (attribute == null) {
  66. return;
  67. }
  68. SessionUser user = (SessionUser) ((SimplePrincipalCollection) attribute)
  69. .getPrimaryPrincipal();
  70. if (!username.equals(user.getUserName())) {
  71. return;
  72. }
  73. // 删除session
  74. if (isRemoveSession) {
  75. shiroResdisSessionDAO.delete(session);
  76. }
  77. DefaultWebSecurityManager securityManager = (DefaultWebSecurityManager) SecurityUtils
  78. .getSecurityManager();
  79. Authenticator authc = securityManager.getAuthenticator();
  80. // 删除cache,在访问受限接口时会重新授权
  81. ((LogoutAware) authc).onLogout((SimplePrincipalCollection) attribute);
  82. }
  83. public void kickOutAllUsers() {
  84. Collection<Session> sessions = shiroResdisSessionDAO.getActiveSessions();
  85. SessionUser user;
  86. Object attribute;
  87. for (Session session : sessions) {
  88. attribute = session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
  89. if (attribute == null) {
  90. continue;
  91. }
  92. user = (SessionUser) ((SimplePrincipalCollection) attribute).getPrimaryPrincipal();
  93. if (user == null) {
  94. continue;
  95. }
  96. shiroResdisSessionDAO.delete(session);
  97. DefaultWebSecurityManager securityManager = (DefaultWebSecurityManager) authorizationAttributeSourceAdvisor.getSecurityManager();
  98. Authenticator authc = securityManager.getAuthenticator();
  99. // 删除cache,在访问受限接口时会重新授权
  100. ((LogoutAware) authc).onLogout((SimplePrincipalCollection) attribute);
  101. log.error("用户强制登出,用户名:{},用户id:{}",user.getRealName(),user.getId());
  102. }
  103. }
  104. }

发表评论

表情:
评论列表 (有 0 条评论,113人围观)

还没有评论,来说两句吧...

相关阅读