csdn_qiangge 2017-05-11 09:28 采纳率: 0%
浏览 6095
已结题

cas与shiro整合,通过trick获取不到用户信息

配置说明:

服务端:4.0
tomcat:8
JDK:1.8

协议:由于领导要求,所以关闭了https协议,也没有使用证书(不知道有木有影响)

客户端:spring boot + shiro(所以要与cas整合)

JDK:1.7

由于一直报错,验证不通过,所以我下载了源码,进入到源码中,还是不理解问题,所以问问大家。希望可以给个思路,谢谢。
首先,在访问客户端时,重定向到了服务端的登录界面
图片说明
输入完用户名和密码后,客户端被casFilter拦截,进入到CasFilter中的onAccessDenied(ServletRequest request, ServletResponse response){return executeLogin(request, response);}
进入到executeLogin(request, response)的实现方法中,进入到AuthenticatingFilter实现的executeLogin方法中,相应代码如下:

 protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
        AuthenticationToken token = createToken(request, response);
        if (token == null) {
            String msg = "createToken method implementation returned null. A valid non-null AuthenticationToken " +
                    "must be created in order to execute a login attempt.";
            throw new IllegalStateException(msg);
        }
        try {
            Subject subject = getSubject(request, response);
            subject.login(token);
            return onLoginSuccess(token, subject, request, response);
        } catch (AuthenticationException e) {
            return onLoginFailure(token, e, request, response);
        }
    }

往下走,首先创建一个CasToken,只有一个参数trick(ST-1-1ZAXXNbLLKfsbB1h5Glz-cas01.example.org),代码如下:

     protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) throws Exception {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        String ticket = httpRequest.getParameter(TICKET_PARAMETER);
        return new CasToken(ticket);
    }

下一步,根据token开始执行subject.login(token); 走到这一步,我不知道我的客户端配置有没有问题,继续往下看,在DelegatingSubject中实现的login方法:

 public void login(AuthenticationToken token) throws AuthenticationException {
        clearRunAsIdentities();
        Subject subject = securityManager.**login(this, token)**;

        PrincipalCollection principals;

        String host = null;

继续securityManager.login(this, token);进入到类DefaultSecurityManager实现方法中:

 public Subject login(Subject subject, AuthenticationToken token) throws AuthenticationException {
        AuthenticationInfo info;
        try {
            info = **authenticate(token)**;
        } catch (AuthenticationException ae) {
            try {
                onFailedLogin(token, ae, subject);
            } catch (Exception e) {
                if (log.isInfoEnabled()) {
                    log.info("onFailedLogin method threw an " +
                            "exception.  Logging and propagating original AuthenticationException.", e);
                }
            }
            throw ae; //propagate
        }

继续看:info = authenticate(token); 进入到类AuthenticatingSecurityManager实现的方法中:

  public AuthenticationInfo authenticate(AuthenticationToken token) throws AuthenticationException {
        return this.authenticator.**authenticate(token)**;
    }

继续进入实现方法中,在类AbstractAuthenticator中实现的代码如下:

 public final AuthenticationInfo authenticate(AuthenticationToken token) throws AuthenticationException {

        if (token == null) {
            throw new IllegalArgumentException("Method argumet (authentication token) cannot be null.");
        }

        log.trace("Authentication attempt received for token [{}]", token);

        AuthenticationInfo info;
        try {
            info = **doAuthenticate(token)**;
            if (info == null) {
                String msg = "No account information found for authentication token [" + token + "] by this " +
                        "Authenticator instance.  Please check that it is configured correctly.";
                throw new AuthenticationException(msg);
            }
        } catch (Throwable t) {

继续进入到doAuthenticate(token)的实现类ModularRealmAuthenticator中,代码如下,大家注意看我加粗的地方, realm.supports(token) :

  protected AuthenticationInfo doSingleRealmAuthentication(Realm realm, AuthenticationToken token) {
        if (!**realm.supports(token)**) {
            String msg = "Realm [" + realm + "] does not support authentication token [" +
                    token + "].  Please ensure that the appropriate Realm implementation is " +
                    "configured correctly or that the realm accepts AuthenticationTokens of this type.";
            throw new UnsupportedTokenException(msg);
        }
        AuthenticationInfo info = realm.getAuthenticationInfo(token);
        if (info == null) {
            String msg = "Realm [" + realm + "] was unable to find account data for the " +
                    "submitted AuthenticationToken [" + token + "].";
            throw new UnknownAccountException(msg);
        }
        return info;
    }

继续进入到 realm.supports(token) ;实现类AuthenticatingRealm,方法如下:

   public boolean supports(AuthenticationToken token) {
        return token != null && getAuthenticationTokenClass().isAssignableFrom(token.getClass());
    }

问题就出在这里,在上面的supports方法中两个class对比一直不匹配, 由于CasRealmh中:

 public CasRealm() {
        setAuthenticationTokenClass(CasToken.class);
    }

而我们之前在刚进入CasFilter中时根据trick新生成的Token也是CasToken。一下图片是我调试时截取的:
图片说明
图片说明
根据调试结果显示两个class是一模一样的,可是偏偏返回false,
最后在类ModularRealmAuthenticator的方法中报错:

 protected AuthenticationInfo doSingleRealmAuthentication(Realm realm, AuthenticationToken token) {
        if (!realm.supports(token)) {
            **String msg = "Realm [" + realm + "] does not support authentication token [" +
                    token + "].  Please ensure that the appropriate Realm implementation is " +
                    "configured correctly or that the realm accepts AuthenticationTokens of this type.";
            throw new UnsupportedTokenException(msg);**
        }
        AuthenticationInfo info = realm.getAuthenticationInfo(token);
        if (info == null) {
            String msg = "Realm [" + realm + "] was unable to find account data for the " +
                    "submitted AuthenticationToken [" + token + "].";
            throw new UnknownAccountException(msg);
        }
        return info;
    }

报错内容:

 String msg = "Realm [" + realm + "] does not support authentication token [" +
                    token + "].  Please ensure that the appropriate Realm implementation is " +
                    "configured correctly or that the realm accepts AuthenticationTokens of this type.";

这里困了我好久了, 实在是不知道怎么解决了, 希望大家可以帮我看看。

  • 写回答

2条回答 默认 最新

  • csdn_qiangge 2017-05-11 09:32
    关注

    单点登录的流程, 我不知道是不是按照上面的流程, 如果大家需要配置文件,我可以把配置文件贴出来,由于客户端在上面的supports方法中报错, 所以也一直没有进入到自定义的MyCasRealm中。但是服务端传递过来的信息在jsp页面是可以获取到的,但这明显不能满足项目的需求,我们的客户端是老项目,先有的客户端,然后要整合单点登录。

    评论

报告相同问题?

悬赏问题

  • ¥20 simulink中怎么使用solve函数?
  • ¥30 dspbuilder中使用signalcompiler时报错Error during compilation: Fitter failed,求解决办法
  • ¥15 gwas 分析-数据质控之过滤稀有突变中出现的问题
  • ¥15 没有注册类 (异常来自 HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG))
  • ¥15 知识蒸馏实战博客问题
  • ¥15 用PLC设计纸袋糊底机送料系统
  • ¥15 simulink仿真中dtc控制永磁同步电机如何控制开关频率
  • ¥15 用C语言输入方程怎么
  • ¥15 网站显示不安全连接问题
  • ¥15 51单片机显示器问题