CAS單點(diǎn)登錄的實(shí)現(xiàn)(二)

這篇文章對(duì)CAS單點(diǎn)登錄具體實(shí)現(xiàn)的一些步驟就行講述,至于CAS單點(diǎn)登錄的實(shí)現(xiàn)原理分析,請(qǐng)參看下面這篇文章:

CAS單點(diǎn)登錄原理分析(一) https://blog.csdn.net/qq_41258204/article/details/84036875

CAS 包含兩個(gè)部分:?CAS Server?和?CAS Client?。

CAS Server?:其實(shí)就是一個(gè)war包,CAS框架已經(jīng)提供。只需要把部署到web服務(wù)器上即可,主要負(fù)責(zé)對(duì)用戶的認(rèn)證工作。 在文章末尾的示例項(xiàng)目中提供。

CAS Client:就是開發(fā)過程中的web層, 負(fù)責(zé)處理對(duì)客戶端受保護(hù)資源的訪問請(qǐng)求,需要登錄時(shí),重定向到 CAS Server。不需要對(duì)這個(gè)部分進(jìn)行過多編碼,進(jìn)行簡單配置即可。

一,CAS 服務(wù)端部署

本次使用的CAS服務(wù)端版本是cas-server-4.0.0-release,

1.將cas-server-4.0.0-release\cas-server-4.0.0\modules文件夾下cas-server-webapp-4.0.0.war文件放入 tomcat 目錄下的 webapps 下,文件改名為cas.war,為了訪問時(shí)方便。

2.啟動(dòng)tomcat ,tomcat將自動(dòng)解壓 war 包。訪問tomcat下這個(gè)項(xiàng)目,就能看到它的登錄頁面。

其實(shí)訪問的是服務(wù)端的首頁index.jsp,觀察上面的地址欄,發(fā)現(xiàn)是對(duì)請(qǐng)求地址進(jìn)行了重寫,跳轉(zhuǎn)到了登錄頁面。有些小伙伴奇怪這個(gè)是怎么做到的,通過查看服務(wù)端的index.jsp會(huì)發(fā)現(xiàn),這個(gè)一點(diǎn)也不神奇。

注意:CAS Server服務(wù)端的登錄界面是可以進(jìn)行改動(dòng)的,不然項(xiàng)目上線后,用戶的登錄體驗(yàn)忒差了點(diǎn)。這個(gè)不用擔(dān)心!

3.用戶名和密碼配置

在\apache-tomcat-cas\webapps\cas\WEB-INF目錄下的deployerConfigContext.xml配置

也可以連接數(shù)據(jù)庫查詢用戶名和密碼,這里先寫死。

修改配置,重啟tomcat服務(wù)器,輸入用戶名,密碼,看到success頁面

4.服務(wù)端訪問端口修改

不想使用8080 端口訪問 CAS Server服務(wù)端, 可以修改訪問端口

4.1首先修改tomcat的訪問端口

修改\apache-tomcat-cas\conf目錄的server.xml文件

80為http協(xié)議默認(rèn)端口,下次再訪問tomcat就不用加端口號(hào),修改其它端口也可以。

4.2修改 CAS 配置文件

修改 cas 的 WEB-INF/cas.properties

server.name=http://localhost:80

修改cas項(xiàng)目的訪問路徑(可選)

修改apache-tomcat-cas\conf目錄下的server.xml文件, 添加如下配置

<Context path="" docBase="cas" reloadable="true"/>

完成上述修改,重啟tomcat服務(wù),輸入localhost就可以訪問到登錄頁面

6.本地域名解析(可選)

如果覺得輸入localhost覺得別扭,還可以進(jìn)行域名解析配置,不過這個(gè)域名只能在自己電腦上使用。

6.1修改C:\Windows\System32\drivers\etc目錄下的hosts文件

快設(shè)置一個(gè)自己喜歡的域名吧,記得用管理員身份編輯哦!

6.2不過我更習(xí)慣用下面這種方式配置本地域名解析

注意:這款軟件要以管理員身份運(yùn)行!

這款軟件,在文章末的實(shí)例項(xiàng)目中提供。再次訪問CAS Server服務(wù)端,一切正常。

7.去除CAS的 https 認(rèn)證

使用了https協(xié)議的網(wǎng)站

網(wǎng)站的地址欄前面會(huì)有一個(gè)小鎖,使用https也是為了網(wǎng)站更加安全。

CAS 默認(rèn)使用的是 HTTPS 協(xié)議,如果使用 HTTPS 協(xié)議需要 SSL 安全證書(需向特定的機(jī)構(gòu)申請(qǐng)和購買) ,在開發(fā)測(cè)試階段可以先使用http協(xié)議。

7.1修改 cas 的 WEB-INF/deployerConfigContext.xml

找到如下配置

添加一個(gè)屬性設(shè)置p:requireSecure="false"。默認(rèn)為true,需要安全驗(yàn)證,使用的是https協(xié)議。

bean id="proxyAuthenticationHandler"

? ? ? ? ? class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler"

? ? ? ? ? p:httpClient-ref="httpClient"? p:requireSecure="false"/>

7.2修改 cas 的/WEB-INF/spring-configuration/ticketGrantingTicketCookieGenerator.xml

p:cookieSecure="false"

p:cookieMaxAge="3600"

p:cookieName="CASTGC"

p:cookiePath="/cas"

7.3修改 cas 的 WEB-INF/spring-configuration/warnCookieGenerator.xml

找到上述配置,修改如下

p:cookieSecure="false"

p:cookieMaxAge="3600"

p:cookieName="CASPRIVACY"

p:cookiePath="/cas"

修改完配置,重啟tomcat,訪問CAS Server服務(wù),一切正常。關(guān)閉瀏覽器后,再次打開瀏覽器訪問,直接顯示已經(jīng)登錄。說明cookie有效時(shí)間設(shè)置成功,會(huì)話cookie設(shè)置成了持久性cookie。

8.CAS 修改服務(wù)端登錄頁面

8.1將準(zhǔn)備的登陸頁面login.html 拷貝到 cas 的 WEB-INF\view\jsp\default\ui 目錄下

8.2將原來的 casLoginView.jsp 改名,將 login.html 改名為 casLoginView.jsp

8.3將準(zhǔn)備的login.html需要的 css js img 文件夾拷貝到 cas 目錄下

8.4修改準(zhǔn)備的登錄頁面casLoginView.jsp

對(duì)照原來的登錄頁面進(jìn)行修改

打開原來的登錄頁面,里面引入了top.jsp頁面

在cas的WEB-INF\view\jsp\default\ui\includes目錄下找到top.jsp頁面

<%@ page pageEncoding="UTF-8" %>

<%@ page contentType="text/html; charset=UTF-8" %>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>

<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>

修改完成后,重新訪問CAS Server服務(wù)端,看到頁面修改成功

到這表面看起來都已經(jīng)修改完成,其實(shí)真正的內(nèi)容還沒有修改。form表單,輸入框和登錄按鈕,還需要進(jìn)一步修改。

8.5修改form表單

打開原來的登錄頁面,找到如下部分

<form:form method="post" id="fm1" commandName="${commandName}" htmlEscape="true">

<form:errors path="*" id="msg" cssClass="errors" element="div" htmlEscape="false" />

</form:form>

將上面的form標(biāo)簽復(fù)制到準(zhǔn)備的登錄頁面上,將準(zhǔn)備的登錄頁面的form標(biāo)簽刪除

8.6修改用戶名輸入框

打開原來的登錄頁面,找到如下部分

<form:input cssClass="required" cssErrorClass="error" id="username" size="25" tabindex="1"? accesskey="${userNameAccessKey}" path="username" autocomplete="off" htmlEscape="true" />

將上面的input標(biāo)簽復(fù)制到準(zhǔn)備的登錄頁面上,刪除上面標(biāo)簽中的cssClass,cssErrorClass樣式,換成準(zhǔn)備的登錄頁面上用戶名輸入框的樣式

<form:input class="text" style="color: #FFFFFF !important"? placeholder="請(qǐng)輸入賬戶"? id="username" size="25" tabindex="1"? accesskey="${userNameAccessKey}" path="username" autocomplete="off"? htmlEscape="true" />

8.7修改密碼輸入框

打開原來的登錄頁面,找到如下部分

? <form:password cssClass="required" cssErrorClass="error" id="password" size="25" tabindex="2" path="password"? accesskey="${passwordAccessKey}" htmlEscape="true" autocomplete="off" />

將上面的password標(biāo)簽復(fù)制到準(zhǔn)備的登錄頁面上,刪除上面標(biāo)簽中的cssClass,cssErrorClass樣式,換成準(zhǔn)備的登錄頁面上密碼輸入框的樣式

<form:password? class="text" style="color: #FFFFFF !important; position:absolute; z-index:100;" placeholder="請(qǐng)輸入密碼" id="password" size="25" tabindex="2" path="password"? accesskey="${passwordAccessKey}" htmlEscape="true" autocomplete="off" />

8.8 修改登錄按鈕

打開原來的登錄頁面,找到如下部分

<input type="hidden" name="lt" value="${loginTicket}" />

? ? ? <input type="hidden" name="execution" value="${flowExecutionKey}" />

? ? ? <input type="hidden" name="_eventId" value="submit" />

? ? ? <input class="btn-submit" name="submit" accesskey="l" value="<spring:message code="screen.welcome.button.login" />" tabindex="4" type="submit" />

將上面的內(nèi)容復(fù)制到準(zhǔn)備的登錄頁面上,刪除上面標(biāo)簽中的 class=“btn-submit”,<spring:message code=“screen.welcome.button.login” />,換成準(zhǔn)備的登錄頁面上按鈕的樣式

<a class="act-but submit" href="javascript:document.getElementById('fm1').submit()" style="color: #FFFFFF" name="submit" accesskey="l" value="登錄" tabindex="4"? />登錄</a>

訪問修改好的登錄頁面,當(dāng)輸入用戶名或密碼錯(cuò)誤,給出的提示信息不是很友好

8.9 修改錯(cuò)誤提示

上面的英文錯(cuò)誤提示信息是在cas的 WEB-INF\classes 目錄下的 messages.properties 文件中

authenticationFailure.AccountNotFoundException=Invalid credentials.

authenticationFailure.FailedLoginException=Invalid credentials.

第一個(gè)是用戶名不存在時(shí)的錯(cuò)誤提示

第二個(gè)是密碼錯(cuò)誤的提示

將上面的兩行內(nèi)容復(fù)制到 messages_zh_CN.properties 文件中,這個(gè)文件主要是配置一些中文信息的,這個(gè)里面里面的內(nèi)容是進(jìn)行轉(zhuǎn)碼提示的

這個(gè)跟properties屬性文件很類似,所以可以借助properties文件來完成中文提示內(nèi)容的寫入

將上述內(nèi)容替換掉Invalid credentials英文提示

authenticationFailure.AccountNotFoundException=\u7528\u6237\u540D\u6216\u5BC6\u7801\u9519\u8BEF.

authenticationFailure.FailedLoginException=\u7528\u6237\u540D\u6216\u5BC6\u7801\u9519\u8BEF.

設(shè)置國際化為 zn_CN ,修改cas的WEB-INF目錄下 cas-servlet.xml,優(yōu)先使用配置中文提示信息的messages_zh_CN.properties 文件

搜索en關(guān)鍵字,快速找到這行信息,默認(rèn)使用的是英文國際化

修改為:

<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver"

p:defaultLocale="zh_CN" />

修改完配置后,重啟tomcat,再次訪問CAS Server服務(wù)端

建議每修改一步就刷新頁面進(jìn)行查看,防止出錯(cuò)!

9.CAS server 自定義認(rèn)證方式

9.1打開cas服務(wù)端WEB-INF目錄下的deployerConfigContext.xml文件 ,找到如下配置

以上就是cas默認(rèn)的認(rèn)證方式,把用戶名和密碼寫死在配置文件中。下面自定義認(rèn)證方式,通過數(shù)據(jù)庫中的用戶信息,來認(rèn)證登錄的用戶。

9.2自定義認(rèn)證

主要配置:

數(shù)據(jù)源dataSource,從數(shù)據(jù)庫中查詢用戶信息

密碼加密方式passwordEncoder,可選配置,可以自定義加密方式

認(rèn)證方式?dbAuthHandler,主要引用數(shù)據(jù)源,查詢sql和密碼加密方式都可以自定義

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"

p:driverClass="com.mysql.jdbc.Driver"

p:jdbcUrl="jdbc:mysql://127.0.0.1:3306/cas?characterEncoding=utf8"

p:user="root"

p:password="root" />

<bean id="passwordEncoder"

class="org.jasig.cas.authentication.handler.DefaultPasswordEncoder"

c:encodingAlgorithm="MD5"

p:characterEncoding="UTF-8" />

<bean id="dbAuthHandler"

class="org.jasig.cas.adaptors.jdbc.QueryDatabaseAuthenticationHandler"

p:dataSource-ref="dataSource"

p:sql="select password from t_user where username = ?"

p:passwordEncoder-ref="passwordEncoder"/>

把以上三個(gè)配置復(fù)制到deployerConfigContext.xml文件中最后,修改認(rèn)證方式為自定義認(rèn)證方式

<entry key-ref="dbAuthHandler" value-ref="primaryPrincipalResolver" />

9.3導(dǎo)入相關(guān)jar包

由于自定義認(rèn)證方式使用數(shù)據(jù)庫作為數(shù)據(jù)源,需要在cas\WEB-INF\lib 目錄下導(dǎo)入以下jar包

修改完成后,重啟tomcat,使用數(shù)據(jù)庫中的數(shù)據(jù)進(jìn)行測(cè)試

二, CAS 客戶端配置

1.創(chuàng)建Maven工程(war) cas_shoppingclient,引入CAS客戶端相關(guān)依賴,設(shè)置tomcat的訪問端口8081

<dependencies>

? <!-- CAS客戶端 -->

? <dependency>?

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

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

? ? <version>3.3.3</version>?

</dependency>?

<!-- servlet -->

? <dependency>

? <groupId>javax.servlet</groupId>

? <artifactId>javax.servlet-api</artifactId>

? <version>3.1.0</version>

? <scope>provided</scope>

? </dependency>

? </dependencies>

? <build>

? <plugins>

? <!-- tomcat插件 -->

? <plugin>

? <groupId>org.apache.tomcat.maven</groupId>

? <artifactId>tomcat7-maven-plugin</artifactId>

? <version>2.2</version>

? <configuration>

? <path>/</path>

? <port>8081</port>

? </configuration>

? </plugin>

? <!-- 設(shè)置jdk版本 -->

? <plugin>

? <groupId>org.apache.maven.plugins</groupId>

? <artifactId>maven-compiler-plugin</artifactId>

? <version>3.5.1</version>

? <configuration>

? <source>1.7</source>

? <target>1.7</target>

? <encoding>UTF-8</encoding>

? </configuration>

? </plugin>

? </plugins>

? </build>

在webapp目錄下創(chuàng)建WEB-INF文件夾,添加web.xml文件

web.xml文件主要配置:

單點(diǎn)登出過濾器SingleSignOutFilter:執(zhí)行用戶退出時(shí)的操作(可選)

認(rèn)證過濾器AuthenticationFilter:負(fù)責(zé)用戶認(rèn)證(必須)

ticket驗(yàn)證過濾器Cas20ProxyReceivingTicketValidationFilter:負(fù)責(zé)檢驗(yàn)ticket(必須)

獲取用戶登錄名過濾器

HttpServletRequestWrapperFilter(可選)和AssertionThreadLocalFilter

(可選)

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">

? <listener>

? ? <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>

? </listener>

? <!-- 該過濾器用于實(shí)現(xiàn)單點(diǎn)登出功能,可選配置。 -->

? <filter>

? ? <filter-name>CAS Single Sign Out Filter</filter-name>

? ? <filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>

? </filter>

? <filter-mapping>

? ? <filter-name>CAS Single Sign Out Filter</filter-name>

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

? </filter-mapping>

? <!-- 該過濾器負(fù)責(zé)用戶的認(rèn)證工作,必須啟用它 -->

? <filter>

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

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

? ? <init-param>

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

? ? ? <!-- CAS服務(wù)端如果訪問端口配置為80,訪問路徑配置path="" 下面地址可以改成http://cas.xiaogui.com -->

? ? ? <param-value>http://cas.xiaogui.com:80/cas</param-value>

? ? </init-param>

? ? <init-param>

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

? ? ? <!-- 客戶端地址,用于認(rèn)證成功后,跳轉(zhuǎn)回客戶端 -->

? ? ? <param-value>http://shopping.xiaogui.com:8081</param-value>

? ? </init-param>

? </filter>

? <filter-mapping>

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

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

? </filter-mapping>

? <!-- 該過濾器負(fù)責(zé)對(duì) Ticket 的校驗(yàn)工作,必須啟用它 -->

? <filter>

? ? <filter-name>CAS Validation Filter</filter-name>

? ? <filter-class>?

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

? ? <init-param>

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

? ? ? <!-- CAS服務(wù)端如果訪問端口配置為80,訪問路徑配置path="" 下面地址可以改成http://cas.xiaogui.com -->

? ? ? <param-value>http://cas.xiaogui.com:80/cas</param-value>

? ? </init-param>

? ? <init-param>

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

? ? ? <!-- 客戶端地址,用于認(rèn)證成功后,跳轉(zhuǎn)回客戶端 -->

? ? ? <param-value>http://shopping.xiaogui.com:8081</param-value>

? ? </init-param>

? </filter>

? <filter-mapping>

? ? <filter-name>CAS Validation Filter</filter-name>

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

? </filter-mapping>

? <!-- 該過濾器負(fù)責(zé)實(shí)現(xiàn) HttpServletRequest 請(qǐng)求的包裹, 比如允許開發(fā)者通過

HttpServletRequest 的 getRemoteUser()方法獲得 SSO 登錄用戶的登錄名,可選配置。 -->

? <filter>

? ? <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>

? ? <filter-class>?

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

? </filter>

? <filter-mapping>

? ? <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name>

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

? </filter-mapping>

? <!-- 該過濾器使得開發(fā)者可以通過 org.jasig.cas.client.util.AssertionHolder 來獲取用戶

的登錄名。 比如 AssertionHolder.getAssertion().getPrincipal().getName()。 -->

? <filter>

? ? <filter-name>CAS Assertion Thread Local Filter</filter-name>

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

? </filter>

? <filter-mapping>

? ? <filter-name>CAS Assertion Thread Local Filter</filter-name>

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

? </filter-mapping>

</web-app>

注意:配置CAS Server服務(wù)端地址和CAS Client客戶端地址一定要對(duì)應(yīng)

3.編寫index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"

? ? pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>購物車</title>

</head>

<body>

<h1>歡迎訪問購物車系統(tǒng),當(dāng)前的用戶名:<%=request.getRemoteUser() %></h1>

</body>

</html>

request.getRemoteUser()為獲取遠(yuǎn)程登錄名

4.創(chuàng)建Maven工程(war) cas_payclient客戶端,參照cas_shoppingclient客戶端進(jìn)行配置

5.創(chuàng)建index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"

? ? pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>商品結(jié)算</title>

</head>

<body>

<h1>歡迎訪問商品結(jié)算系統(tǒng),當(dāng)前的用戶名:<%=request.getRemoteUser() %></h1>

</body>

</html>

6.單點(diǎn)登錄測(cè)試

啟動(dòng)cas服務(wù)端

啟動(dòng)客戶端cas_shoppingclient和客戶端cas_payclient

訪問cas_shoppingclient客戶端

輸入帳號(hào),密碼登錄

訪問cas_payclient客戶端

直接登錄成功!

7.cas單點(diǎn)退出登錄到指定頁面

地址欄輸入?http://cas.xiaogui.com/cas/logout

即可看到退出后的提示頁面

自定義退出登錄跳轉(zhuǎn)地址

找到如cas服務(wù)端 WEB-INF目錄的配置文件 cas-servlet.xml如下配置

p:followServiceRedirects="${cas.logout.followServiceRedirects:true}

在cas_shoppingclient客戶端index.jsp頁面上添加一個(gè)退出鏈接

<a >退出登錄</a>

分享示例項(xiàng)目在碼云上的地址:https://gitee.com/xiaoguixiaogege/SSO_CAS

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容