单点登录,shiro+redis+springmvc

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

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

3个回答

老铁!没完全懂你意思,不过写点自己看法:
首先在使用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());
    }
    }
    
pandahii
pandahii 回复chuhx: 希望对你有帮助
2 年多之前 回复
pandahii
pandahii 回复chuhx: 这又篇博文,http://jinnianshilongnian.iteye.com/blog/2036730可以看看!
2 年多之前 回复
pandahii
pandahii 回复chuhx: 呃···你描述的有“客户端根据session也读到了用户权限”& “客户端的shiro拦截”!当你不实现客户端的Realm中的doGetAuthenticationInfo,那么你在使用客户端的shiro拦截的时候又怎么知道是哪个session呢!你不告诉shiro,shiro又怎么知道客户端的session
2 年多之前 回复
chuhx
chuhx 我是想问的问题是,已经在服务端登录成功了。那么这个token怎么传到客户端那?token怎么赋值到shiro里面那?
2 年多之前 回复
chuhx
chuhx 你好!我在服务端已经定义Realm,实现了doGetAuthenticationInfo认证信息方法,如果再在客户端实现doGetAuthenticationInfo认证信息方法, 那么客户端又会产生新的session,就没有起到单点登录的作用了。
2 年多之前 回复

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

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

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问