Shiro CAS对接原理一览

2 篇文章 0 订阅
  1. 用户访问需授权的地址,Shiro拦截请求重定向到cas登录地址,附带service参数
  2. cas登录成功则重定向到service参数指定的地址,附加请求参数token
  3. Shiro拦截请求拿到token,通过http访问cas接口(2.0协议)/serviceValidate附带token和service参数,cas验证token是否有效,有效则cas重定向到service参数指定的地址,附带登录人信息
  4. Shiro获取到登录人信息,调用login(),登录成功

上面第3点,cas可能返回说token无效,但是这个token就是刚才cas返回的,这儿可能需要在cas端配置文件设置token的有效时长。
上面提到service参数,上面各处的参数值都是同一个,在shiro的配置文件中指定的shiro要拦截的地址

单点退出:任一客户端访问cas的登出接口,登录用户登出,cas给所有注册的客户端发送登出请求,里面附有登出的token,客户端依据这个token对服务器中的用户进行退出登录,比如根据token查找session,让session失效且清除session相关的缓存。上面提到注册的客户端,什么时候注册的呢,根据经验我猜想在客户端调用了cas的登录接口,登录成功时注册的。

第3步是在自定义的CasRealm中实现的,CasRealm继承org.apache.shiro.cas.CasRealm

@Override
protected AuthenticationInfo doGetAuthenticationInfo(
            AuthenticationToken token) {
        CasToken casToken = (CasToken) token;
        if (token == null)
            return null;
        String ticket = (String) casToken.getCredentials();
        if (!StringUtils.hasText(ticket))
            return null;
        TicketValidator ticketValidator = ensureTicketValidator();
        try {
            Assertion casAssertion = ticketValidator.validate(ticket,
                    getCasService());
            AttributePrincipal casPrincipal = casAssertion.getPrincipal();
            Map userInfo = casPrincipal.getAttributes();
            String uName = casPrincipal.getName();
            log.debug("Validate ticket : {} in CAS server : {} to retrieve user : {}",
                    new Object[] { ticket, getCasServerUrlPrefix(), uName });

            casToken.setUserId(uName);
            String rememberMeAttributeName = getRememberMeAttributeName();
            String rememberMeStringValue = (String) userInfo
                    .get(rememberMeAttributeName);
            boolean isRemembered = rememberMeStringValue != null
                    && Boolean.parseBoolean(rememberMeStringValue);
            if (isRemembered)
                casToken.setRememberMe(true);
            List principals = Arrays
                    .asList(new Object[] {uName, userInfo });
            PrincipalCollection principalCollection = new SimplePrincipalCollection(
                    principals, getName());


            /*SecurityUtils.getSubject().getSession().setAttribute(Constants.SESSION_ATTR_USER_KEY,
            user);
            SecurityUtils.getSubject().getSession().setAttribute(Constants.SESSION_ATTR_SHIRO_USER_KEY,
            shiroUsr);*/
            return new SimpleAuthenticationInfo(principalCollection, ticket);
        } catch (TicketValidationException e) {
            throw new CasAuthenticationException((new StringBuilder())
                    .append("Unable to validate ticket [").append(ticket)
                    .append("]").toString(), e);
        }

    }
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值