shiro+cas単点登録解決

2962 ワード

本文は主に単点登録の問題を解決して、A応用が退出した後に、同一のCAS TGT手形を共有するB応用も退出することを実現する
プロセスを終了します.
1、Aアプリケーションが終了した場合、casサービス側に要求し、サービス側手形を破棄する
2、casサービス側は単点登録のBアプリケーションに脱退要求を送信する
3、Bアプリケーションは要求を受け取った後、終了する
シングル・サインオフの公式ソリューション:
Webでxmlで対応するリスナーとフィルタを構成すればよい

    
        org.jasig.cas.client.session.SingleSignOutHttpSessionListener
    
    
    
        CAS Single Sign Out Filter
        org.jasig.cas.client.session.SingleSignOutFilter
    
    
        CAS Single Sign Out Filter
        /*
    

しかし、公式ソリューションは標準的なhttpセッションのみを処理しており、プロジェクトでShiro Sessionを使用して管理していると、公式ソリューションでは単一のログイン効果は得られません.CASサーバから送信されたlogout要求を受信した場合には,Shiro Sessionを破棄する論理を自己処理する必要がある.
最終的な解決方法:
1、まずCAS Tokenを記録し、ログイン後CAS Serverコールバック時に行う.Tokenとsession idをバインドします(HashMap).
/**
     * Associates a token request with the current HTTP session by recording the mapping
     * in the the configured {@link SessionMappingStorage} container.
     * 
     * @param request HTTP request containing an authentication token.
     */
    public void recordSession(final HttpServletRequest request) {
        final HttpSession session = request.getSession(this.eagerlyCreateSessions);

        if (session == null) {
            logger.debug("No session currently exists (and none created).  Cannot record session information for single sign out.");
            return;
        }

        final String token = CommonUtils.safeGetParameter(request, this.artifactParameterName);
        logger.debug("Recording session for token {}", token);

        try {
            this.sessionMappingStorage.removeBySessionById(session.getId());
        } catch (final Exception e) {
            // ignore if the session is already marked as invalid. Nothing we can do!
        }
        sessionMappingStorage.addSessionById(token, session);
    }

2、その後CAS Serverからの登録要求(要求にtokenがある)を受け取った場合、tokenに従ってHashMapからsession idを取得し、session idをクリーンアップマーク(例:session.setAttribute(「isLogout」、true)とする.
この場合,登録処理を直接行うことはできず,logoutメソッドを持つShiro Subjectオブジェクトはスレッドにバインドされているため,ここでは正しいSubjectオブジェクトを取得することはできない.
3、ユーザーが再度ウェブサイトを使用する場合、このときユーザーのセッションIDがクリーンアップとしてマークされているかどうかをチェックし、マークされている場合はSubjectオブジェクトのlogoutメソッドを削除して、登録処理を行う.
Subject subject = SecurityUtils.getSubject();
Session session = subject.getSession(false);
if (session!=null&&session.getAttribute("isLogout")!=null && (boolean)session.getAttribute("isLogout")) {
    try {
        subject.logout();
    } catch (SessionException ise) {
        logger.debug("Encountered session exception during logout.  This can generally safely be ignored.", ise);
    }