chuhx 2017-07-14 02:13 采纳率: 100%
浏览 2174
已采纳

单点登录,shiro+redis+springmvc

我现在遇到一个问题。客户端根据session也读到了用户权限,但是客户端的shiro拦截报PrincipalCollection为空

授权信息怎么赋给客户端的PrincipalCollection里面?

  • 写回答

3条回答 默认 最新

  • pandahii 2017-07-14 02:51
    关注

    老铁!没完全懂你意思,不过写点自己看法:
    首先在使用shiro时候是存在一个叫Realm类,这个类主要实现根据提交PrincipalCollection的获取授权信息,其次该类还提供认证方法。在整体流程上,

    • 1.认证时即登陆,当调用SecurityUtils.getSubject().login(token)的时候,程序会调用<定义的Realm>中的认证方法doGetAuthenticationInfo
    • 2.授权时即访问的<定义授权列表>,程序会调用<定义的Realm>中的认证方法doGetAuthorizationInfo

    突然感觉你说的PrincipalCollection为空,应该是token为空造成的,这个token可使用shiro的UsernamePasswordToken进行构造,也可以自己继承定义

    • 在xml中定义的Realm 如下 <bean id="realm" class="xxx.xxx.xxx.Realm" /> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <property name="realm" ref="realm" /> </bean>
    • Realm类

      public class Realm extends AuthorizingRealm {
      
      ...
      
      /**
       * 授权信息
       */
      protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
      
          // 获取请求用户名
          String username = (String) principals.getPrimaryPrincipal()
          // 查询数据库,获得用户相关信息,如角色,权限等
          User user = service.find(username);
      
          // 角色名、权限名的集合
          Set<String> roles = new HashSet<String>();
          Set<String> permissions = new HashSet<String>();
      
          // 将角色名和权限名放入shiro里
          for (Iterator<Role> roleItr = user.getRoles().iterator(); roleItr.hasNext();) {
              Role role = roleItr.next();
              if (role != null) {
                  roles.add(role.getName());
                  for (Iterator<Permission> perItr = role.getPermissions().iterator(); perItr.hasNext();) {
                      Permission per = perItr.next();
                      if (per != null) {
                          permissions.add(per.getName());
                      }
                  }
              }
          }
      
          SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
          authorizationInfo.addRoles(roles);
          authorizationInfo.addStringPermissions(permissions);
          return authorizationInfo;
      }
      
      /**
       * 认证信息
       */
      protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken)
              throws AuthenticationException {
          UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
          ...
          return new SimpleAuthenticationInfo(username, password, getName());
      }
      
      @PostConstruct
      public void initCredentialsMatcher() {
      
          // 该句作用是重写shiro的密码验证,让shiro使用自定义验证
          setCredentialsMatcher(new CustomCredentialsMatcher());
      }
      }
      
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?