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

单点登录,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());
      }
      }
      
    点赞 打赏 评论
  • chuhx 2017-07-14 03:18

    你好!我在服务端已经定义Realm,实现了doGetAuthenticationInfo认证信息方法,如果再在客户端实现doGetAuthenticationInfo认证信息方法,
    那么客户端又会产生新的session,就没有起到单点登录的作用了。

    点赞 打赏 评论
  • john93 2019-05-10 11:40

    你好,可以分享一下ssm,shiro,redis单点登陆源码?

    点赞 打赏 评论

相关推荐 更多相似问题