CAS單點登錄的實現(二)

這篇文章對CAS單點登錄具體實現的一些步驟就行講述,至於CAS單點登錄的實現原理分析,請參看下面這篇文章:
CAS單點登錄原理分析(一) https://blog.csdn.net/qq_41258204/article/details/84036875

CAS 包含兩個部分: CAS Server CAS Client

CAS Server :其實就是一個war包,CAS框架已經提供。只需要把部署到web服務器上即可,主要負責對用戶的認證工作。 在文章末尾的示例項目中提供。

CAS Client:就是開發過程中的web層, 負責處理對客戶端受保護資源的訪問請求,需要登錄時,重定向到 CAS Server。不需要對這個部分進行過多編碼,進行簡單配置即可。

一,CAS 服務端部署

本次使用的CAS服務端版本是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,爲了訪問時方便。

2.啓動tomcat ,tomcat將自動解壓 war 包。訪問tomcat下這個項目,就能看到它的登錄頁面。

在這裏插入圖片描述

其實訪問的是服務端的首頁index.jsp,觀察上面的地址欄,發現是對請求地址進行了重寫,跳轉到了登錄頁面。有些小夥伴奇怪這個是怎麼做到的,通過查看服務端的index.jsp會發現,這個一點也不神奇。

在這裏插入圖片描述

在這裏插入圖片描述

注意:CAS Server服務端的登錄界面是可以進行改動的,不然項目上線後,用戶的登錄體驗忒差了點。這個不用擔心!

3.用戶名和密碼配置

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

在這裏插入圖片描述

也可以連接數據庫查詢用戶名和密碼,這裏先寫死。

修改配置,重啓tomcat服務器,輸入用戶名,密碼,看到success頁面

在這裏插入圖片描述

4.服務端訪問端口修改

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

4.1首先修改tomcat的訪問端口

修改\apache-tomcat-cas\conf目錄的server.xml文件
在這裏插入圖片描述

80爲http協議默認端口,下次再訪問tomcat就不用加端口號,修改其它端口也可以。

4.2修改 CAS 配置文件

修改 cas 的 WEB-INF/cas.properties

server.name=http://localhost:80
  1. 修改cas項目的訪問路徑(可選)

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

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

在這裏插入圖片描述

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

在這裏插入圖片描述

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

如果覺得輸入localhost覺得彆扭,還可以進行域名解析配置,不過這個域名只能在自己電腦上使用。

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

在這裏插入圖片描述

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

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

在這裏插入圖片描述

在這裏插入圖片描述

注意:這款軟件要以管理員身份運行!

這款軟件,在文章末的實例項目中提供。再次訪問CAS Server服務端,一切正常。
在這裏插入圖片描述

7.去除CAS的 https 認證

在這裏插入圖片描述

使用了https協議的網站
在這裏插入圖片描述

網站的地址欄前面會有一個小鎖,使用https也是爲了網站更加安全。

CAS 默認使用的是 HTTPS 協議,如果使用 HTTPS 協議需要 SSL 安全證書(需向特定的機構申請和購買) ,在開發測試階段可以先使用http協議。

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

找到如下配置

在這裏插入圖片描述

添加一個屬性設置p:requireSecure="false"。默認爲true,需要安全驗證,使用的是https協議。

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服務,一切正常。關閉瀏覽器後,再次打開瀏覽器訪問,直接顯示已經登錄。說明cookie有效時間設置成功,會話cookie設置成了持久性cookie。

8.CAS 修改服務端登錄頁面

8.1將準備的登陸頁面login.html 拷貝到 cas 的 WEB-INF\view\jsp\default\ui 目錄下
在這裏插入圖片描述

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

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

在這裏插入圖片描述

8.4修改準備的登錄頁面casLoginView.jsp

對照原來的登錄頁面進行修改

打開原來的登錄頁面,裏面引入了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服務端,看到頁面修改成功

在這裏插入圖片描述

到這表面看起來都已經修改完成,其實真正的內容還沒有修改。form表單,輸入框和登錄按鈕,還需要進一步修改。

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標籤複製到準備的登錄頁面上,將準備的登錄頁面的form標籤刪除
在這裏插入圖片描述

8.6修改用戶名輸入框

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

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

將上面的input標籤複製到準備的登錄頁面上,刪除上面標籤中的cssClass,cssErrorClass樣式,換成準備的登錄頁面上用戶名輸入框的樣式

 <form:input class="text" style="color: #FFFFFF !important"  placeholder="請輸入賬戶"  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標籤複製到準備的登錄頁面上,刪除上面標籤中的cssClass,cssErrorClass樣式,換成準備的登錄頁面上密碼輸入框的樣式

<form:password  class="text" style="color: #FFFFFF !important; position:absolute; z-index:100;" placeholder="請輸入密碼" 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" />

將上面的內容複製到準備的登錄頁面上,刪除上面標籤中的 class=“btn-submit”,<spring:message code=“screen.welcome.button.login” />,換成準備的登錄頁面上按鈕的樣式

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

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

在這裏插入圖片描述

8.9 修改錯誤提示

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

在這裏插入圖片描述

authenticationFailure.AccountNotFoundException=Invalid credentials. 
authenticationFailure.FailedLoginException=Invalid credentials.

第一個是用戶名不存在時的錯誤提示
第二個是密碼錯誤的提示

將上面的兩行內容複製到 messages_zh_CN.properties 文件中,這個文件主要是配置一些中文信息的,這個裏面裏面的內容是進行轉碼提示的

在這裏插入圖片描述

這個跟properties屬性文件很類似,所以可以藉助properties文件來完成中文提示內容的寫入

在這裏插入圖片描述

將上述內容替換掉Invalid credentials英文提示

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

設置國際化爲 zn_CN ,修改cas的WEB-INF目錄下 cas-servlet.xml,優先使用配置中文提示信息的messages_zh_CN.properties 文件

搜索en關鍵字,快速找到這行信息,默認使用的是英文國際化
在這裏插入圖片描述

修改爲:

<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver"
p:defaultLocale="zh_CN" />

修改完配置後,重啓tomcat,再次訪問CAS Server服務端

在這裏插入圖片描述

建議每修改一步就刷新頁面進行查看,防止出錯!

9.CAS server 自定義認證方式

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

在這裏插入圖片描述

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

9.2自定義認證

主要配置:
數據源dataSource,從數據庫中查詢用戶信息
密碼加密方式passwordEncoder,可選配置,可以自定義加密方式
認證方式 dbAuthHandler,主要引用數據源,查詢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"/>

把以上三個配置複製到deployerConfigContext.xml文件中最後,修改認證方式爲自定義認證方式
在這裏插入圖片描述

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

9.3導入相關jar包
由於自定義認證方式使用數據庫作爲數據源,需要在cas\WEB-INF\lib 目錄下導入以下jar包
在這裏插入圖片描述

修改完成後,重啓tomcat,使用數據庫中的數據進行測試

在這裏插入圖片描述

在這裏插入圖片描述

在這裏插入圖片描述

二, CAS 客戶端配置

1.創建Maven工程(war) cas_shoppingclient,引入CAS客戶端相關依賴,設置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>
  			<!-- 設置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>
  1. 在webapp目錄下創建WEB-INF文件夾,添加web.xml文件

web.xml文件主要配置:

單點登出過濾器SingleSignOutFilter:執行用戶退出時的操作(可選)

認證過濾器AuthenticationFilter:負責用戶認證(必須)

ticket驗證過濾器Cas20ProxyReceivingTicketValidationFilter:負責檢驗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>
  <!-- 該過濾器用於實現單點登出功能,可選配置。 -->
  <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>
  <!-- 該過濾器負責用戶的認證工作,必須啓用它 -->
  <filter>
    <filter-name>CASFilter</filter-name>
    <filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
    <init-param>
      <param-name>casServerLoginUrl</param-name>
      <!-- CAS服務端如果訪問端口配置爲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>
      <!-- 客戶端地址,用於認證成功後,跳轉回客戶端 -->
      <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>
  <!-- 該過濾器負責對 Ticket 的校驗工作,必須啓用它 -->
  <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服務端如果訪問端口配置爲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>
      <!-- 客戶端地址,用於認證成功後,跳轉回客戶端 -->
      <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>
  <!-- 該過濾器負責實現 HttpServletRequest 請求的包裹, 比如允許開發者通過
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>
  <!-- 該過濾器使得開發者可以通過 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服務端地址和CAS Client客戶端地址一定要對應

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>歡迎訪問購物車系統,當前的用戶名:<%=request.getRemoteUser() %></h1>
</body>
</html>

request.getRemoteUser()爲獲取遠程登錄名

4.創建Maven工程(war) cas_payclient客戶端,參照cas_shoppingclient客戶端進行配置

5.創建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>歡迎訪問商品結算系統,當前的用戶名:<%=request.getRemoteUser() %></h1>
</body>
</html>

6.單點登錄測試

啓動cas服務端
啓動客戶端cas_shoppingclient和客戶端cas_payclient
訪問cas_shoppingclient客戶端
在這裏插入圖片描述

輸入帳號,密碼登錄
在這裏插入圖片描述

訪問cas_payclient客戶端
在這裏插入圖片描述

直接登錄成功!

7.cas單點退出登錄到指定頁面

地址欄輸入 http://cas.xiaogui.com/cas/logout
即可看到退出後的提示頁面
在這裏插入圖片描述

自定義退出登錄跳轉地址

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

在這裏插入圖片描述

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

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

<a href="http://cas.xiaogui.com/cas/logout?service=https://blog.csdn.net/qq_41258204">退出登錄</a>

在這裏插入圖片描述

分享示例項目在碼雲上的地址:https://gitee.com/xiaoguixiaogege/SSO_CAS

未完,待續!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章