亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

Cas(07)——建立使用Cas進(jìn)行單點登錄的應(yīng)用

系統(tǒng) 1790 0

建立使用 Cas 進(jìn)行單點登錄的應(yīng)用

?

目錄

1.1 加入 cas-client-core-xxx.jar classpath

1.2 配置 Filter

1.2.1 AuthenticationFilter

1.2.2 TicketValidationFilter

1.2.3 HttpServletRequestWrapperFilter

1.2.4 AssertionThreadLocalFilter

1.2.5 基于 Spring Filter 配置

1.3 添加證書到信任庫

?

?????? 根據(jù)之前的描述我們知道, Cas 由兩部分組成, Cas Server Cas Client Cas Server Cas 自己的服務(wù)端,而 Cas Client Cas 客戶端,其需要與我們自己的應(yīng)用進(jìn)行集成。

?

1.1 ???? 加入 cas-client-core-xxx.jar classpath

?????? 在我們下載的 Cas Client 壓縮包的 modules 目錄下可以找到一個名為 cas-client-core-xxx.jar jar 文件,首先需要將該 jar 包加入我們應(yīng)用的類路徑下,筆者這里使用的是 cas-client-core-3.1.11.jar 。如果用戶的應(yīng)用是使用 Maven 構(gòu)造的,則可以在應(yīng)用的 pom.xml 文件中加入如下依賴。

?? < dependency >

????? < groupId > org.jasig.cas.client </ groupId >

????? < artifactId > cas -client-core </ artifactId >

????? < version > 3.1.11 </ version >

?? </ dependency >

?

1.2 ???? 配置 Filter

?????? 然后需要我們在應(yīng)用的 web.xml 文件中配置四個 Filter ,這四個 Filter 必須按照固定的順序來進(jìn)行配置,而且它們必須配置在應(yīng)用的其它 Filter 之前。它們的先后順序要求如下:

l ? AuthenticationFilter

l ? TicketValidationFilter

l ? HttpServletRequestWrapperFilter

l ? AssertionThreadLocalFilter

?

?????? 這些 Filter 有的必須指定某些參數(shù),有的可以指定某些參數(shù),這些參數(shù)可以通過 context-param 來指定,也可以通過 init-param 來指定。 Cas Client 默認(rèn)會先從 init-param 取,沒取到則從 context-param 取,所以當(dāng) init-param context-param 都指定了某個參數(shù)時, init-param 指定的將擁有更高的優(yōu)先級。所以當(dāng)多個 Filter 需要共用一個參數(shù)時,我們可以把它定義為 context-param

?

1.2.1 ??? AuthenticationFilter

?????? AuthenticationFilter 用來攔截所有的請求,用以判斷用戶是否需要通過 Cas Server 進(jìn)行認(rèn)證,如果需要則將跳轉(zhuǎn)到 Cas Server 的登錄頁面。如果不需要進(jìn)行登錄認(rèn)證,則請求會繼續(xù)往下執(zhí)行。

???? AuthenticationFilter 有兩個用戶必須指定的參數(shù),一個是用來指定 Cas Server 登錄地址的 casServerLoginUrl ,另一個是用來指定認(rèn)證成功后需要跳轉(zhuǎn)地址的 serverName service service serverName 只需要指定一個就可以了。當(dāng)兩者都指定了,參數(shù) service 將具有更高的優(yōu)先級,即將以 service 指定的參數(shù)值為準(zhǔn)。 service serverName 的區(qū)別在于 service 指定的是一個確定的 URL ,認(rèn)證成功后就會確切的跳轉(zhuǎn)到 service 指定的 URL ;而 serverName 則是用來指定主機名,其格式為 {protocol}:{hostName}:{port} ,如: https://localhost:8443 ,當(dāng)指定的是 serverName 時, AuthenticationFilter 將會把它附加上當(dāng)前請求的 URI ,以及對應(yīng)的查詢參數(shù)來構(gòu)造一個確定的 URL ,如指定 serverName 為“ http://localhost ”,而當(dāng)前請求的 URI 為“ /app ”,查詢參數(shù)為“ a=b&b=c ”,則對應(yīng)認(rèn)證成功后的跳轉(zhuǎn)地址將為“ http://localhost/app?a=b&b=c ”。

?

?????? 除了上述必須指定的參數(shù)外, AuthenticationFilter 還可以指定如下可選參數(shù):

l ? renew :當(dāng)指定 renew true 時,在請 Cas Server 時將帶上參數(shù)“ renew=true ”,默認(rèn)為 false

l ? gateway :指定 gateway true 時,在請求 Cas Server 時將帶上參數(shù)“ gateway=true ”,默認(rèn)為 false

l ? artifactParameterName :指定 ticket 對應(yīng)的請求參數(shù)名稱,默認(rèn)為 ticket

l ? serviceParameterName :指定 service 對應(yīng)的請求參數(shù)名稱,默認(rèn)為 service

?

?????? 如下是一個配置 AuthenticationFilter 的示例, serverName 由于在接下來配置的 Filter 中還要用,所以利用 context-param 將其配置為一個公用的參數(shù)。“ elim ”對應(yīng)我的電腦名。

?

?? < context-param >

????? < param-name > serverName </ param-name >

????? < param-value > http://elim:8080 </ param-value >

?? </ context-param >

??

?? < filter >

????? < filter-name > casAuthenticationFilter </ filter-name >

?? < filter-class > org.jasig.cas.client.authentication.AuthenticationFilter </ filter-class >

????? < init-param >

???????? < param-name > casServerLoginUrl </ param-name >

???????? < param-value > https://elim:8443/cas/login </ param-value >

????? </ init-param >

?? </ filter >

?? < filter-mapping >

????? < filter-name > casAuthenticationFilter </ filter-name >

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

?? </ filter-mapping >

?

1.2.2 ??? TicketValidationFilter

?????? 在請求通過 AuthenticationFilter 的認(rèn)證之后,如果請求中攜帶了參數(shù) ticket 則將會由 TicketValidationFilter 來對攜帶的 ticket 進(jìn)行校驗。 TicketValidationFilter 只是對驗證 ticket 的這一類 Filter 的統(tǒng)稱,其并不對應(yīng) Cas Client 中的一個具體類型。 Cas Client 中有多種驗證 ticket Filter ,都繼承自 AbstractTicketValidationFilter ,它們的驗證邏輯都是一致的,都有 AbstractTicketValidationFilter 實現(xiàn),所不同的是使用的 TicketValidator 不一樣。筆者這里將以 Cas10TicketValidationFilter 為例,其它還有 Cas20ProxyReceivingTicketValidationFilter Saml11TicketValidationFilter

?

?? < filter >

????? < filter-name > casTicketValidationFilter </ filter-name >

?? < filter-class > org.jasig.cas.client.validation.Cas10TicketValidationFilter </ filter-class >

????? < init-param >

???????? < param-name > casServerUrlPrefix </ param-name >

???????? < param-value > https://elim:8443/cas </ param-value >

????? </ init-param >

?? </ filter >

?? < filter-mapping >

????? < filter-name > casTicketValidationFilter </ filter-name >

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

?? </ filter-mapping >

?

?????? 必須指定的參數(shù):

l ? casServerUrlPrefix :用來指定 Cas Server 對應(yīng) URL 地址的前綴,如上面示例的“ https://elim:8443/cas ”。

l ? serverName service :語義跟前面介紹的一致。

?

?????? 可選參數(shù):

l ? redirectAfterValidation ? :表示是否驗證通過后重新跳轉(zhuǎn)到該 URL ,但是不帶參數(shù) ticket ,默認(rèn)為 true

l ? useSession ? :在驗證 ticket 成功后會生成一個 Assertion 對象,如果 useSession true ,則會將該對象存放到 Session 中。如果為 false ,則要求每次請求都需要攜帶 ticket 進(jìn)行驗證,顯然 useSession false redirectAfterValidation true 是沖突的。默認(rèn)為 true

l ? exceptionOnValidationFailure ? :表示 ticket 驗證失敗后是否需要拋出異常,默認(rèn)為 true

l ? renew :當(dāng)值為 true 時將發(fā)送“ renew=true ”到 Cas Server ,默認(rèn)為 false

?

1.2.3 ??? HttpServletRequestWrapperFilter

?????? HttpServletRequestWrapperFilter 用于將每一個請求對應(yīng)的 HttpServletRequest 封裝為其內(nèi)部定義的 CasHttpServletRequestWrapper ,該封裝類將利用之前保存在 Session request 中的 Assertion 對象重寫 HttpServletRequest getUserPrincipal() getRemoteUser() isUserInRole() 方法。這樣在我們的應(yīng)用中就可以非常方便的從 HttpServletRequest 中獲取到用戶的相關(guān)信息。以下是一個配置 HttpServletRequestWrapperFilter 的示例:

?? < filter >

????? < filter-name > casHttpServletRequestWrapperFilter </ filter-name >

?? < filter-class > org.jasig.cas.client.util.HttpServletRequestWrapperFilter </ filter-class >

?? </ filter >

?? < filter-mapping >

????? < filter-name > casHttpServletRequestWrapperFilter </ filter-name >

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

?? </ filter-mapping >

?

1.2.4 ??? AssertionThreadLocalFilter

?????? AssertionThreadLocalFilter 是為了方便用戶在應(yīng)用的其它地方獲取 Assertion 對象,其會將當(dāng)前的 Assertion 對象存放到當(dāng)前的線程變量中,那么以后用戶在程序的任何地方都可以從線程變量中獲取當(dāng)前 Assertion ,無需再從 Session request 中進(jìn)行解析。該線程變量是由 AssertionHolder 持有的,我們在獲取當(dāng)前的 Assertion 時也只需要通過 AssertionHolder getAssertion() 方法獲取即可,如:

?? Assertion assertion = AssertionHolder. getAssertion ();

?

?????? AssertionThreadLocalFilter 這種設(shè)計理念是非常好的,實際應(yīng)用中使用的也比較多, Spring Security 中也有用到這種理念。為了便于大家了解,特貼出 AssertionHolder 的源碼如下:

public? class AssertionHolder {

?

??? /**

???? * ThreadLocal to hold the Assertion for Threads to access.

???? */

??? private? static? final ThreadLocal threadLocal = new ThreadLocal();

?

?

??? /**

???? * Retrieve the assertion from the ThreadLocal.

???? */

??? public? static Assertion getAssertion() {

??????? return (Assertion) threadLocal .get();

??? }

?

??? /**

???? * Add the Assertion to the ThreadLocal.

???? */

??? public? static? void setAssertion( final Assertion assertion) {

??????? threadLocal .set(assertion);

??? }

?

??? /**

???? * Clear the ThreadLocal.

???? */

??? public? static? void clear() {

??????? threadLocal .set( null );

??? }

}

?

?????? 以下是配置 AssertionThreadLocalFilter 的示例:

?? < filter >

????? < filter-name > casAssertionThreadLocalFilter </ filter-name >

?? ? < filter-class > org.jasig.cas.client.util.AssertionThreadLocalFilter </ filter-class >

?? </ filter >

?? < filter-mapping >

????? < filter-name > casAssertionThreadLocalFilter </ filter-name >

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

?? </ filter-mapping >

?

1.2.5 ??? 基于Spring的Filter配置

?????? 使用 Cas 單點登錄的應(yīng)用需要我們在應(yīng)用的 web.xml 文件中配置上述介紹的四個 Filter ,但如果用戶的應(yīng)用是使用 Spring 開發(fā)的,則我們可以只在 web.xml 文件中配置四個 Spring DelegatingFilterProxy 用來代理需要配置的四個 Filter ,對應(yīng)的 Filter 名稱對應(yīng)我們需要代理的 Spring ApplicationContext bean 的名稱,此時我們需要將對應(yīng)的 Filter 配置為 Spring ApplicationContext 中的一個 bean 對象。所以此時對應(yīng)的 web.xml 文件的定義應(yīng)該是這樣的:

?? < filter >

????? < filter-name > casAuthenticationFilter </ filter-name >

?? ? < filter-class > org.springframework.web.filter.DelegatingFilterProxy </ filter-class >

?? </ filter >

?? < filter-mapping >

????? < filter-name > casAuthenticationFilter </ filter-name >

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

?? </ filter-mapping >

?

?? < filter >

????? < filter-name > casTicketValidationFilter </ filter-name >

?? ? < filter-class > org.springframework.web.filter.DelegatingFilterProxy </ filter-class >

?? </ filter >

?? < filter-mapping >

????? < filter-name > casTicketValidationFilter </ filter-name >

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

?? </ filter-mapping >

?

?? < filter >

????? < filter-name > casHttpServletRequestWrapperFilter </ filter-name >

?? ? < filter-class > org.springframework.web.filter.DelegatingFilterProxy </ filter-class >

?? </ filter >

?? < filter-mapping >

????? < filter-name > casHttpServletRequestWrapperFilter </ filter-name >

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

?? </ filter-mapping >

?

?? < filter >

????? < filter-name > casAssertionThreadLocalFilter </ filter-name >

?? ? < filter-class > org.springframework.web.filter.DelegatingFilterProxy </ filter-class >

?? </ filter >

?? < filter-mapping >

????? < filter-name > casAssertionThreadLocalFilter </ filter-name >

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

?? </ filter-mapping >

?

?????? 而對應(yīng)的 Filter 應(yīng)該都以對應(yīng)的名稱定義為 Spring ApplicationContext 中的一個 bean

?? < bean name = "casAuthenticationFilter"

????? class = "org.jasig.cas.client.authentication.AuthenticationFilter"

????? p:casServerLoginUrl = "https://elim:8443/cas/login" p:renew = "false"

????? p:gateway = "false" p:serverName = "http://elim:8080" />

?

?? < bean name = "casTicketValidationFilter"

????? class = "org.jasig.cas.client.validation.Cas10TicketValidationFilter"

????? p:serverName = "http://elim:8080" p:redirectAfterValidation = "true" >

????? < property name = "ticketValidator" >

???????? < bean class = "org.jasig.cas.client.validation.Cas10TicketValidator" >

??????????? <!-- 對應(yīng)于 casServerUrlPrefix -->

??????????? < constructor-arg index = "0" value = "https://elim:8443/cas" />

???????? </ bean >

????? </ property >

?? </ bean >

?

?? < bean id = "casHttpServletRequestWrapperFilter" class = "org.jasig.cas.client.util.HttpServletRequestWrapperFilter" />

??

?? < bean id = "casAssertionThreadLocalFilter" class = "org.jasig.cas.client.util.AssertionThreadLocalFilter" />

?

1.3 ???? 添加證書到信任庫

?????? ticket 驗證成功后,還需要驗證證書,這需要我們將之前建立的證書導(dǎo)出并添加到當(dāng)前 JRE 的證書信任庫中,否則將驗證失敗。 JRE 在尋找證書時將根據(jù)當(dāng)前使用的 host 來尋找,且會用該 host 匹配之前創(chuàng)建證書時指定的用戶名稱,如果匹配則表示找到。這也就意味著我們在 創(chuàng)建證書時指定的用戶名稱需要是我們的 host 。我的機器名稱為“ elim ”,我就把它作為我的 host ,那么對應(yīng)的證書應(yīng)該這樣創(chuàng)建。

keytool -genkey -keyalg RSA -alias tomcat -dname "cn=elim" -storepass changeit

?

?????? 該語句是對我們之前介紹的 keytool -genkey -alias tomcat -keyalg RSA 的精寫,它已經(jīng)通過相應(yīng)的參數(shù)指定了對應(yīng)的參數(shù)值,而不需要再與用戶交互了。如果還用之前的語句生成證書的話,那么對應(yīng)的值應(yīng)該這樣填:


Cas(07)——建立使用Cas進(jìn)行單點登錄的應(yīng)用
?

?

?????? 之后會在用戶的對應(yīng)目錄下生成一個 .keystore 文件。之后需要將該文件導(dǎo)出為一個證書到 %JAVA_HOME%/jre/lib/security 目錄下,對應(yīng)指令為:

keytool -export -alias tomcat -file %JAVA_HOME%/jre/lib/security/tomcat.crt -storepass changeit

?

?????? 之后需要將導(dǎo)出的 tomcat.crt 證書添加到運行時使用的 JRE 的受信任證書庫中,此時如果出現(xiàn)異常可將原本 %JAVA_HOME%/jre/lib/security 目錄下的 cacerts 刪除后繼續(xù)執(zhí)行以下指令。

keytool -import -alias tomcat -file %JAVA_HOME%/jre/lib/security/tomcat.crt -keystore %JAVA_HOME%/jre/lib/security/cacerts -storepass changeit

?

?????? 經(jīng)過以上幾步后就可以啟用我們自己的 Cas Client 應(yīng)用了,然后初次訪問該應(yīng)用時就會跳轉(zhuǎn)到 Cas Server 進(jìn)行登錄認(rèn)證。認(rèn)證成功后將跳轉(zhuǎn)到我們自己的 Client 應(yīng)用進(jìn)行 ticket 的驗證,驗證通過后就可以自由的訪問我們的 Client 應(yīng)用了。

?

(注:本文是基于 Cas Server3.5.2 Cas Client3.1.11 所寫)

(注:原創(chuàng)文章,轉(zhuǎn)載請注明出處。原文地址: http://haohaoxuexi.iteye.com/blog/2142631

?

?

?

Cas(07)——建立使用Cas進(jìn)行單點登錄的應(yīng)用


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 四虎永久精品免费网址大全 | 国产精品手机网站 | 天天干天天操天天干 | 国产成人在线播放视频 | 天天干天天爽天天射 | 天天操天天舔天天射 | 亚洲精品国产成人中文 | 成人国产午夜在线视频 | 国产成人免费视频精品一区二区 | 亚洲成人高清在线 | 日本精品中文字幕在线不卡 | 欧美曰批人成在线观看 | 亚洲狠狠操 | 国内精品哆啪啪 | 国产成人精品综合 | 成人老司机深夜福利久久 | 日日干夜夜草 | 337p粉嫩大胆色噜噜噜 | 99精品久久久久久久 | 色婷婷视频在线 | 四虎免费影院4hu永久免费 | 国产精品一区视频 | 久久精品国产久精国产 | 妖精视频永久在线入口 | 中国国语毛片免费观看视频 | 免费一级欧美大片在线观看 | 日韩第1页 | 日本嫩小xxxxhd | 中日韩一区二区三区 | 99久久99热久久精品免 | 99国产精品免费视频观看 | 久久福利青草免费精品 | 波多结衣一区二区三区 | 91亚洲国产三上悠亚在线播放 | 中文字幕一区在线观看视频 | 欧美视频色 | 女人洗澡一级毛片一级毛片 | 四虎影城| 国产妇乱子伦视频免费 | 深夜福利国产福利视频 | 欧美在线观看一区二区 |