日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

JForum論壇單點(diǎn)登錄的幾種實(shí)現(xiàn)方式 (CAS和Cookie)

 CevenCheng 2011-08-07
JForum論壇單點(diǎn)登錄的幾種實(shí)現(xiàn)方式 (CAS和Cookie)
0評(píng)/451閱
發(fā)表于: 2011-04-23 13:15 作者: abao
  • 用CAS實(shí)現(xiàn)Jforum的單點(diǎn)登錄

 

(一)CAS客戶端應(yīng)用的web.xml配置

CAS和jforum的安裝過程本文就不介紹了,下面是jforum配置CAS服務(wù)器連接需要在web.xml中添加的配置:

   <filter>

        <filter-name>CASFilter</filter-name>

        <filter-class>edu.yale.its.tp.cas.client.filter.CASFilter</filter-class>

        <init-param>

            <param-name>edu.yale.its.tp.cas.client.filter.loginUrl</param-name>

            <param-value>https://localhost:8443/cas/login</param-value>

        </init-param>

        <init-param>

            <param-name>edu.yale.its.tp.cas.client.filter.validateUrl</param-name>

            <param-value>https://localhost:8443/cas/proxyValidate</param-value>

        </init-param>

        <init-param>

          <param-name>edu.yale.its.tp.cas.client.filter.serverName</param-name>

          <param-value>localhost:8000</param-value>

        </init-param>

    </filter>

    <filter-mapping>

        <filter-name>CASFilter</filter-name>

        <url-pattern>/*</url-pattern>

    </filter-mapping>

 

一開始我調(diào)試jforum的單點(diǎn)登錄的時(shí)候,首先在地址欄輸入http://localhost:8000/cas/login?service=http://localhost:8000/jforum/user.jsp

(其中user.jsp是我自己添加JSP頁面做測(cè)試用 ),在CAS頁面輸入用戶名和口令確認(rèn)后,頁面自動(dòng)跳轉(zhuǎn)到http://localhost:8000/jforum/user.jsp?ticket= ticket=ST-5-Ih4fJNYyWlhFfywfeOwuVAFZn1vKOOVAgpD-20

Ticket是生成的票據(jù),然后用這個(gè)ticket做參數(shù)訪問:

https://localhost:8443/cas/serviceValidate?service= http://localhost:8000/jforum/user.jsp&ticket= ST-5-Ih4fJNYyWlhFfywfeOwuVAFZn1vKOOVAgpD-20

如果成功,返回的頁面中出現(xiàn)登錄成功的用戶名,打開html源文件,內(nèi)容為:

<cas:serviceResponse xmlns:cas='http://www./tp/cas'>

       <cas:authenticationSuccess>

              <cas:user>admin</cas:user>

       </cas:authenticationSuccess>

</cas:serviceResponse>

如果失敗,頁面顯示ticket 'ST-2-4ffpnvHKv1NH5So7uWvFdVNrbHsaPAfROXx-20' not recognized,html源文件內(nèi)容:

<cas:serviceResponse xmlns:cas='http://www./tp/cas'>

       <cas:authenticationFailure code='INVALID_TICKET'>

              ticket 'ST-2-4ffpnvHKv1NH5So7uWvFdVNrbHsaPAfROXx-20' not recognized

       </cas:authenticationFailure>

</cas:serviceResponse>

(二)Jforum配置單點(diǎn)登錄

Jforum的WEB-INF\config目錄下有一個(gè)SystemGlobals.properties文件,配置SSO需要更改此文件的幾個(gè)配置參數(shù):

authentication.type = sso

#CasUserSSO類用于CAS單點(diǎn)登錄,下面將講述此類的代碼

sso.implementation = com.iss.common.sso.CasUserSSO

#CasCookieSSO是基于Cookie的一個(gè)簡(jiǎn)單的單點(diǎn)登錄,代碼見下文

#sso.implementation = com.iss.common.sso.CasCookieSSO

#下面的redirect我也不太清楚具體有什么用

sso.redirect = https://localhost:8443/cas/

(三)當(dāng)把jforum的web.xml的CAS filter注釋掉以后,使用下面的JSP通過CAS單點(diǎn)登錄票據(jù)驗(yàn)證的一個(gè)示例,其中URL應(yīng)帶service參數(shù),如:

http://localhost:8000/cas/login?service=http://localhost:8000/jforum/testsso.jsp

登錄CAS成功后,返回的頁面url帶有一個(gè)ticket參數(shù),見下面的返回URL:

http://localhost:8000/jforum/testsso.jsp?ticket=ST-5-VbM7tdMPeLD1WlH2ZGnocVGTbAY73ff4y17-20

Tomcat控制臺(tái)顯示下面的輸出說明票據(jù)認(rèn)證通過:

<cas:serviceResponse xmlns:cas='http://www./tp/cas'>

        <cas:authenticationSuccess>

                <cas:user>admin</cas:user>

        </cas:authenticationSuccess>

</cas:serviceResponse>

下面是testsso.jsp:

 

<%@ page contentType="text/html;charset=GBK"%>

 

<%@ page import="java.util.*"%> 

<%@ page import="net.jforum.context.RequestContext"%> 

<%@ page import="net.jforum.entities.UserSession"%> 

<%@ page import="net.jforum.util.preferences.ConfigKeys"%> 

<%@ page import="net.jforum.util.preferences.SystemGlobals"%> 

<%@ page import="org.apache.log4j.Logger"%> 

<%@ page import="net.jforum.sso.*"%> 

 

<%@ page import="java.io.*"%> 

<%@ page import="edu.yale.its.tp.cas.client.*"%> 

<%

    String username = null;

      String errorCode = null;

      String errorMessage = null;

      String xmlResponse = null;

      String ticket = request.getParameter("ticket");

    System.out.println("獲取的ticket為:"+ticket);

       ServiceTicketValidator sv = new ServiceTicketValidator();

        if(ticket != null)

        {

            try

            {

         

                sv.setCasValidateUrl("https://localhost:8443/cas/serviceValidate");

             sv.setServiceTicket(ticket);

                sv.setService("http://localhost:8000/jforum/testsso.jsp");

             sv.validate();  

             xmlResponse = sv.getResponse();

               

              if (sv.isAuthenticationSuccesful())

                {

                 username = sv.getUser();

                     System.out.println("認(rèn)證成功,獲得的用戶名為:");

                     System.out.println(username);

             }

                else

                {

                  errorCode = sv.getErrorCode();

                    errorMessage = sv.getErrorMessage();

                     System.out.println("認(rèn)證失敗?。。。。。。。。。。?);

             }

            }

            catch (Exception exc)

            {

               System.out.println(exc.getMessage());

          }

      }

%>

 

edu.yale.its.tp.cas.client.ServiceTicketValidator是casclient.jar中的類。

 

(四)當(dāng)Jforum的web.xml中不配置CAS Filter時(shí),如何實(shí)現(xiàn)單點(diǎn)登錄類?

這種情況類似于(三),但問題是如何在Java類中實(shí)現(xiàn)單點(diǎn)登錄,而不是在jsp中實(shí)現(xiàn)。

我從網(wǎng)上找到一個(gè)名為CasUserSSO.java的程序,并按步驟(二)的說明將此類作為單點(diǎn)登錄類配置,但編譯運(yùn)行后,在瀏覽器地址欄輸入http://localhost:8000/cas/login?service=http://localhost:8000/jforum/user.jsp

(user.jsp是我自己寫的一個(gè)顯示簡(jiǎn)單輸出的jsp文件, http://localhost:8000/jforum/user.jsp是我在CasUserSSO.java里面作為service參數(shù)的),CAS登錄成功后Tomcat控制臺(tái)沒有顯示單點(diǎn)登錄的認(rèn)證信息,好象CasUserSSO沒有調(diào)用到,于是我修改了CasUserSSO.java,將

sv.setService("http://localhost:8000/jforum/user.jsp")改為sv.setService(java.net.URLEncoder.encode(http://localhost:8000/jforum/forums/jforum.page?module=forums&action=list"));

重新編譯運(yùn)行后,地址欄中輸入http://localhost:8000/cas/login?service= http%3A%2F%2Flocalhost%3A8000%2Fjforum%2Fforums%2Fjforum.page%3Fmodule%3Dforums%26action%3Dlist

注意service等號(hào)右面的必須是java.net.URLEncoder.encode轉(zhuǎn)換后的字符串(http://localhost:8000/jforum/forums/jforum.page?module=forums&action=list轉(zhuǎn)換后的字符串為http%3A%2F%2Flocalhost%3A8000%2Fjforum%2Fforums%2Fjforum.page%3Fmodule%3Dforums%26action%3Dlist)

 

注意地址欄中service后不要帶空格,在地址欄輸入http://localhost:8000/cas/login?service=http%3A%2F%2Flocalhost%3A8000%2Fjforum%2Fforums%2Fjforum.page%3Fmodule%3Dforums%26action%3Dlist,CAS登錄后(我的jforum配的超級(jí)管理員賬號(hào)是admin/123),出現(xiàn)jforum頁面,這說明CAS單點(diǎn)登錄成功?。?!

Tomcat控制臺(tái)顯示:

 

<cas:serviceResponse xmlns:cas='http://www./tp/cas'>

        <cas:authenticationSuccess>

                <cas:user>admin</cas:user>

        </cas:authenticationSuccess>

</cas:serviceResponse>

 

請(qǐng)大家一定要注意,在地址欄中service=后面的URL必須是encode轉(zhuǎn)換后的,因?yàn)殚_始沒轉(zhuǎn)換,我還以為是CasUserSSO寫的有問題,網(wǎng)上下載的CasUserSSO中的

sv.setCasValidateUrl("https://localhost:8443/cas/login");我認(rèn)為是有問題的,會(huì)出現(xiàn)一個(gè)很奇怪的異常,顯示信息為org.xml.sax.SAXParseException: The reference to entity "ticket" must end with the ';' delimiter.我改為:

sv.setCasValidateUrl("https://localhost:8443/cas/serviceValidate")則不會(huì)出現(xiàn)這個(gè)問題。見下面的CasUserSSO.java:

 

package com.iss.common.sso;

 

import net.jforum.context.RequestContext;

import net.jforum.entities.UserSession;

import net.jforum.util.preferences.ConfigKeys;

import net.jforum.util.preferences.SystemGlobals;

import org.apache.log4j.Logger;

import net.jforum.sso.*;

import java.util.*;

import java.net.*;

 

import edu.yale.its.tp.cas.client.*;

 

public class CasUserSSO implements SSO

{

    static final Logger logger = Logger.getLogger(CasUserSSO.class.getName());

    public String authenticateUser(RequestContext request)

    {

        String username = null;

      String errorCode = null;

      String errorMessage = null;

      String xmlResponse = null;

     // 開始setServiceTicket單點(diǎn)登錄代碼

 

      String ticket = request.getParameter("ticket");

        logger.info("獲取的ticket為:"+ticket);

 

       ServiceTicketValidator sv = new ServiceTicketValidator();

       

      if(ticket != null)

        {

                       try

            {

                logger.info("ticket為非空!!!!!!!!!!!!!!!!!");

                sv.setCasValidateUrl("https://localhost:8443/cas/serviceValidate");

                //sv.setCasValidateUrl("https://localhost:8443/cas/login");

                System.out.println(java.net.URLEncoder.encode("http://localhost:8000/jforum/forums/jforum.page?module=forums&action=list"));

                sv.setService(java.net.URLEncoder.encode("http://localhost:8000/jforum/forums/jforum.page?module=forums&action=list"));

                sv.setServiceTicket(ticket);

             logger.info("開始驗(yàn)證............");

             sv.validate();  

             xmlResponse = sv.getResponse();

                //System.out.println(xmlResponse);

              if (sv.isAuthenticationSuccesful())

                {

                 username = sv.getUser();

                    logger.info("認(rèn)證成功,獲得的用戶名為:");

                    logger.info(username);

             }

                else

                {

                  errorCode = sv.getErrorCode();

                    errorMessage = sv.getErrorMessage();

                    logger.info("認(rèn)證失?。。。。。。。。。。?!");

             }

            }

            catch (Exception exc)

            {

               System.out.println(exc.getMessage());

          }

      }

        // 結(jié)束setServiceTicket單點(diǎn)登錄代碼

       

       /* System.out.println("開始獲取用戶名。。。");

        username = (String)request.getSessionContext().getAttribute("edu.yale.its.tp.cas.client.filter.user");

        System.out.println(username);

        System.out.println("結(jié)束獲取用戶名。。。");

 

        logger.info("登錄用戶為:"+username);*/

        return username;

    }

 

    public boolean isSessionValid(UserSession userSession,RequestContext request)

    {

        ServiceTicketValidator sv = new ServiceTicketValidator();

      String remoteUser =sv.getUser();  

        logger.info("RemoteUser為");

        logger.info(remoteUser);

        //user has since logged out

      if (remoteUser == null && userSession.getUserId() != SystemGlobals.getIntValue(ConfigKeys.ANONYMOUS_USER_ID))

        {

          return false;

      }

     

        // user has since logged in

      else if (remoteUser != null && userSession.getUserId() == SystemGlobals.getIntValue(ConfigKeys.ANONYMOUS_USER_ID))

        {

          return false;

      }

      // user has changed user

      else if (remoteUser != null && !remoteUser.equals(userSession.getUsername()))

        {

          return false;

      }   

      return true;

    }

}

 

通過http://localhost:8000/cas/login?service=http%3A%2F%2Flocalhost%3A8000%2Fjforum%2Fforums%2Fjforum.page%3Fmodule%3Dforums%26action%3Dlist登錄成功后(admin/123),jforum顯示的頁面為admin的已登錄頁面,如果這時(shí)在當(dāng)前瀏覽器輸入配置了CAS的其他web應(yīng)用,其他web應(yīng)用不會(huì)彈出cas登錄頁面,因?yàn)閏as已經(jīng)登錄過了。我做了一個(gè)測(cè)試,首先

打開一個(gè)新的瀏覽器窗口,輸入一個(gè)配置了CAS的web應(yīng)用地址,如http://localhost:8000/cms

,彈出cas登錄窗口,輸入admin/123,登錄成功,這時(shí)候再輸入http://localhost:8000/cas/login?service=http%3A%2F%2Flocalhost%3A8000%2Fjforum%2Fforums%2Fjforum.page%3Fmodule%3Dforums%26action%3Dlist,仍然出來一個(gè)CAS登錄窗口,這好象不是我們所希望的,那么只好再把jforum的web.xml中的CAS過濾器配置好。

(五)當(dāng)Jforum的web.xml中配置了CAS Filter時(shí),如何實(shí)現(xiàn)單點(diǎn)登錄類?

現(xiàn)在我們按(一)的說明配置好CAS Filter,重啟tomcat,再次輸入http://localhost:8000/cas/login?service=http%3A%2F%2Flocalhost%3A8000%2Fjforum%2Fforums%2Fjforum.page%3Fmodule%3Dforums%26action%3Dlist,反而后臺(tái)報(bào)出認(rèn)證失敗的錯(cuò)誤,Tomcat的控制臺(tái)輸出:

 

<cas:serviceResponse xmlns:cas='http://www./tp/cas'>

        <cas:authenticationFailure code='INVALID_TICKET'>

                ticket 'ST-8-DWSSawgxWPwjjJwkScbIOqDcqR6eTUdZhwi-20' not recogni

zed

        </cas:authenticationFailure>

</cas:serviceResponse>

 

難道上面的CasUserSSO.java的ServiceTicketValidator的那段代碼只適用于未配置CAS Filter的情況?還是因?yàn)榕渲昧薈AS Filter后,CAS自動(dòng)做了ticket的驗(yàn)證后丟掉了ticket?所以CasUserSSO中取到的ticket已經(jīng)過期?這個(gè)問題我沒想明白,大家如果有清楚的話可以交流一下。

我現(xiàn)在想到一個(gè)問題,既然配了Cas Filter后,那么CAS登錄后在session里有用戶信息,為什么不直接從session中取呢?見上面的CasUserSSO.java,注釋掉// 開始setServiceTicket單點(diǎn)登錄代碼和// 結(jié)束setServiceTicket單點(diǎn)登錄代碼之間的代碼,使用下面的代碼獲得用戶名:

 

        username = (String)request.getSessionContext().getAttribute("edu.yale.its.tp.cas.client.filter.user ");

 

這樣豈不更直接!其中CAS登錄成功后,配置了CAS Filter的Web應(yīng)用的session都可以通過edu.yale.its.tp.cas.client.filter.user取得用戶名,然后我們重新編譯CasUserSSO.java,并啟動(dòng)tomcat,

這時(shí)再按下面的過程測(cè)試一下單點(diǎn)登錄,首先新打開一個(gè)瀏覽器,輸入http://localhost:8000/cms(此Web應(yīng)用已配置了CAS),CAS登錄窗口輸入admin/123(cms應(yīng)用的admin的口令和jforum的可以不同),登錄成功后,再運(yùn)行:

http://localhost:8000/jforum/forums/jforum.page?module=forums&action=list

不會(huì)再出來登錄窗口了,此頁面是系統(tǒng)管理員admin已登錄的頁面。

 

注意:如果CAS登錄通過了一個(gè)jforum目前沒有的帳戶,則訪問jforum時(shí)jforum會(huì)自動(dòng)在數(shù)據(jù)庫表(jforum_users)中插入一條新的記錄,換句話說就是能自動(dòng)注冊(cè),如果其他Web應(yīng)用需要和jforum集成的話,只要配好了單點(diǎn)登錄,就不需要擔(dān)心其他應(yīng)用的用戶在jforum中注冊(cè)的問題(不過自動(dòng)注冊(cè)只填寫賬號(hào)名,其他字段還需要用戶自己維護(hù),或者編程實(shí)現(xiàn)從另外的應(yīng)用數(shù)據(jù)庫中將用戶詳細(xì)信息與jforum中的用戶相關(guān)信息進(jìn)行同步)。

(六)使用Cookie實(shí)現(xiàn)單點(diǎn)等錄

 

由于CAS的配置比較復(fù)雜。在實(shí)際的企業(yè)應(yīng)用中部署CAS比較麻煩,有的企業(yè)的應(yīng)用服務(wù)器是WebSphere的,因此還要解決CAS如何在Websphere部署的問題,同時(shí)CAS的用戶認(rèn)證接口還要進(jìn)行開發(fā),CAS的性能能否滿足注冊(cè)用戶信息量很大的電子商務(wù)網(wǎng)站?已有系統(tǒng)如何與CAS集成?等等很多問題需要我們考慮,如果我們只需要將Jforum論壇和電子商務(wù)平臺(tái)集成起來,可以考慮采用Cookie進(jìn)行單點(diǎn)登錄的認(rèn)證(我們項(xiàng)目只要求登錄電子商務(wù)頁面后進(jìn)入論壇不用再登錄而不是相反),用Cookie做單點(diǎn)登錄的實(shí)現(xiàn)方式:

(1)電子商務(wù)平臺(tái)登錄成功后(不是基于CAS的,把用戶名寫到名為bbsUser的Cookie中)

(2)為保證安全性,Cookie只在電子商務(wù)應(yīng)用服務(wù)器中有效(和Jforum在同一應(yīng)用服務(wù)器運(yùn)行,cookie.setPAth(“/”)),并且Cookie的MaxAge設(shè)置為-1,就是瀏覽器關(guān)閉后Cookie自動(dòng)失效,另外session失效時(shí)也刪除名為bbsUser的Cookie)

 

所以控制層和JSP中可參考下面代碼創(chuàng)建Cookie:

        Cookie[] cookie1 = request.getCookies();  

         if(cookie1==null)

         {

             Cookie cookie = new Cookie("bbsUser", acegiUserName);

             cookie.setMaxAge(-1);   //負(fù)值表示瀏覽器關(guān)閉時(shí)cookie被刪除,零值則是要?jiǎng)h除該Cookie。

             cookie.setPath("/");

             response.addCookie(cookie);

         }

         else

         {

             for(int i=0; i< cookie1.length; i++)

             {  

                 String name = cookie1[i].getName();  

                 String value = cookie1[i].getValue();  

                 if(!name.equals("bbsUser"))  //已存在cookie則不需要增加cookie,否則增加cookie

                 {

                     Cookie cookie = new Cookie("bbsUser", acegiUserName);

                     cookie.setMaxAge(-1);   //負(fù)值表示瀏覽器關(guān)閉時(shí)cookie被刪除,零值則是要?jiǎng)h除該Cookie。

                     cookie.setPath("/"); //cookie只在同一應(yīng)用服務(wù)器有效

                     response.addCookie(cookie);

                 }

             }

         }     

 

瀏覽器關(guān)閉,上面的cookie失效,如果session失效,則失效跳轉(zhuǎn)或login.jsp要清除cookie,代碼:

  //清除bbsUser的cookie

   Cookie cookie = new Cookie("bbsUser", "");

   cookie.setMaxAge(0);   //負(fù)值表示瀏覽器關(guān)閉時(shí)cookie被刪除,零值則是要?jiǎng)h除該Cookie。

   cookie.setPath("/");

   response.addCookie(cookie);

 

下面是在JForum中使用的CasCookieSSO.java,此代碼從Cookie中讀取名為bbsUser的Cookie作為用戶名:

package com.iss.common.sso;

 

import net.jforum.context.RequestContext;

import net.jforum.entities.UserSession;

import net.jforum.util.preferences.ConfigKeys;

import net.jforum.util.preferences.SystemGlobals;

import org.apache.log4j.Logger;

import net.jforum.sso.*;

import java.util.*;

import java.net.*;

import javax.servlet.http.Cookie;

 

public class CasCookieSSO implements SSO

{

    static final Logger logger = Logger.getLogger(CasUserSSO.class.getName());

    public String authenticateUser(RequestContext request)

    {

        String username = null;

      String errorCode = null;

      String errorMessage = null;

      String xmlResponse = null;

 

        Cookie[] cookie = request.getCookies();  

        if(cookie == null)

        {

            //username = "guest";

        }

        else

        {

            for(int i=0; i< cookie.length; i++)

            {  

                String name = cookie[i].getName();  

                String value = cookie[i].getValue(); 

                if(name.equals("bbsUser"))

                {

                    username = value;

                    break; //退出循環(huán)

                }

            }

        }     

       

        logger.info("登錄用戶為:"+username);

        return username;

    }

 

    public boolean isSessionValid(UserSession userSession,RequestContext request)

    {

        return false;

        //說明:為什么在這里返回false,因?yàn)槿绻祷豻rue的話,當(dāng)cookie中的用戶id變化后,再次訪問jforum時(shí),

        //jforum仍記憶上次使用的用戶ID,當(dāng)其他應(yīng)用改變登錄用戶后,不能根據(jù)cookie中的bbsUser變量切換為新的用戶,將返回值設(shè)置為false后問題解決。所以這里推薦直接返回false。

    }

}

使用CasCookieSSO時(shí),注意更改Jforum的配置文件,sso.implementation = com.iss.common.sso. CasCookieSSO。 

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多