本文主要介紹 CAS 客戶端的接入,使用到的軟體版本:JDK 1.8.0_191、Tomcat 8.5.76、SpringBoot 2.5.11、CAS 5.3.16、CAS Client 3.6.4,
1、服務端準備
這里假設服務端已經安裝完畢,地址為:http://127.0.0.1:8080/cas,服務端的安裝方法可參考:CAS 入門實戰(2)--服務端安裝,
2、普通 Java Web 應用接入
這里客戶端的應用地址為:http://127.0.0.1:9090/cas-client,
2.1、引入依賴
<dependency> <groupId>org.jasig.cas.client</groupId> <artifactId>cas-client-core</artifactId> <version>3.6.4</version> </dependency>
如果不是使用 maven 來構建專案,可以手動下載對應的包后放到應用的 lib 下,
2.2、配置 AuthenticationFilter
該型別過濾器用于檢測用戶是否需要進行身份驗證;如果需要,則會將用戶重定向到 CAS 服務器,有兩個可選的過濾器:
org.jasig.cas.client.authentication.AuthenticationFilter
org.jasig.cas.client.authentication.Saml11AuthenticationFilter
這里使用 org.jasig.cas.client.authentication.AuthenticationFilter,在 web.xml 增加如下配置:
<filter> <filter-name>CAS Authentication Filter</filter-name> <filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class> <init-param> <param-name>casServerUrlPrefix</param-name> <param-value>http://127.0.0.1:8080/cas</param-value> </init-param> <init-param> <param-name>serverName</param-name> <param-value>http://127.0.0.1:9090</param-value> </init-param> </filter> <filter-mapping> <filter-name>CAS Authentication Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
org.jasig.cas.client.authentication.AuthenticationFilter 過濾器的引數說明如下:
| Property | Description | Required |
|---|---|---|
casServerUrlPrefix |
The start of the CAS server URL, i.e. https://localhost:8443/cas |
Yes (unless casServerLoginUrl is set) |
casServerLoginUrl |
Defines the location of the CAS server login URL, i.e. https://localhost:8443/cas/login. This overrides casServerUrlPrefix, if set. |
Yes (unless casServerUrlPrefix is set) |
serverName |
The name of the server this application is hosted on. Service URL will be dynamically constructed using this, i.e. https://localhost:8443 (you must include the protocol, but port is optional if it's a standard port). | Yes |
service |
The service URL to send to the CAS server, i.e. https://localhost:8443/yourwebapp/index.html |
No |
renew |
specifies whether renew=true should be sent to the CAS server. Valid values are either true/false (or no value at all). Note that renew cannot be specified as local init-param setting. |
No |
gateway |
specifies whether gateway=true should be sent to the CAS server. Valid values are either true/false (or no value at all) |
No |
artifactParameterName |
specifies the name of the request parameter on where to find the artifact (i.e. ticket). |
No |
serviceParameterName |
specifies the name of the request parameter on where to find the service (i.e. service) |
No |
encodeServiceUrl |
Whether the client should auto encode the service url. Defaults to true |
No |
ignorePattern |
Defines the url pattern to ignore, when intercepting authentication requests. | No |
ignoreUrlPatternType |
Defines the type of the pattern specified. Defaults to REGEX. Other types are CONTAINS, EXACT, FULL_REGEX. Can also accept a fully-qualified class name that implements UrlPatternMatcherStrategy. |
No |
gatewayStorageClass |
The storage class used to record gateway requests | No |
authenticationRedirectStrategyClass |
The class name of the component to decide how to handle authn redirects to CAS | No |
method |
The method used by the CAS server to send the user back to the application. Defaults to null |
No |
ignoreUrlPatternType 支持的型別說明如下:
| Type | Description |
|---|---|
REGEX |
Matches the URL the ignorePattern using Matcher#find(). It matches the next occurrence within the substring that matches the regex. |
CONTAINS |
Uses the String#contains() operation to determine if the url contains the specified pattern. Behavior is case-sensitive. |
EXACT |
Uses the String#equals() operation to determine if the url exactly equals the specified pattern. Behavior is case-sensitive. |
FULL_REGEX |
Matches the URL the ignorePattern using Matcher#matches(). It matches the expression against the entire string as it implicitly add a ^ at the start and $ at the end of the pattern, so it will not match substring or part of the string. ^ and $ are meta characters that represents start of the string and end of the string respectively. |
2.3、配置 TicketValidationFilter
該型別過濾器負責對票據進行驗證,有多個可選的過濾器:
org.jasig.cas.client.validation.Cas10TicketValidationFilter
org.jasig.cas.client.validation.Saml11TicketValidationFilter
org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter
org.jasig.cas.client.validation.Cas30ProxyReceivingTicketValidationFilter
org.jasig.cas.client.validation.json.Cas30JsonProxyReceivingTicketValidationFilter
這里使用 org.jasig.cas.client.validation.Cas30ProxyReceivingTicketValidationFilter,在 web.xml 增加如下配置:
<filter> <filter-name>CAS Validation Filter</filter-name> <filter-class>org.jasig.cas.client.validation.Cas30ProxyReceivingTicketValidationFilter</filter-class> <init-param> <param-name>casServerUrlPrefix</param-name> <param-value>http://127.0.0.1:8080/cas</param-value> </init-param> <init-param> <param-name>serverName</param-name> <param-value>http://127.0.0.1:9090</param-value> </init-param> </filter> <filter-mapping> <filter-name>CAS Validation Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
org.jasig.cas.client.validation.Cas30ProxyReceivingTicketValidationFilter 過濾器的引數說明如下:
| Property | Description | Required |
|---|---|---|
casServerUrlPrefix |
The start of the CAS server URL, i.e. https://localhost:8443/cas |
Yes |
serverName |
The name of the server this application is hosted on. Service URL will be dynamically constructed using this, i.e. https://localhost:8443 (you must include the protocol, but port is optional if it's a standard port). |
Yes |
renew |
Specifies whether renew=true should be sent to the CAS server. Valid values are either true/false (or no value at all). Note that renew cannot be specified as local init-param setting. |
No |
redirectAfterValidation |
Whether to redirect to the same URL after ticket validation, but without the ticket in the parameter. Defaults to true. |
No |
useSession |
Whether to store the Assertion in session or not. If sessions are not used, tickets will be required for each request. Defaults to true. |
No |
exceptionOnValidationFailure |
whether to throw an exception or not on ticket validation failure. Defaults to true |
No |
proxyReceptorUrl |
The URL to watch for PGTIOU/PGT responses from the CAS server. Should be defined from the root of the context. For example, if your application is deployed in /cas-client-app and you want the proxy receptor URL to be /cas-client-app/my/receptor you need to configure proxyReceptorUrl to be /my/receptor. |
No |
acceptAnyProxy |
Specifies whether any proxy is OK. Defaults to false. |
No |
allowedProxyChains |
Specifies the proxy chain. Each acceptable proxy chain should include a space-separated list of URLs (for exact match) or regular expressions of URLs (starting by the ^ character). Each acceptable proxy chain should appear on its own line. |
No |
proxyCallbackUrl |
The callback URL to provide the CAS server to accept Proxy Granting Tickets. | No |
proxyGrantingTicketStorageClass |
Specify an implementation of the ProxyGrantingTicketStorage class that has a no-arg constructor. | No |
sslConfigFile |
A reference to a properties file that includes SSL settings for client-side SSL config, used during back-channel calls. The configuration includes keys for protocol which defaults to SSL, keyStoreType, keyStorePath, keyStorePass, keyManagerType which defaults to SunX509 and certificatePassword. |
No. |
encoding |
Specifies the encoding charset the client should use | No |
secretKey |
The secret key used by the proxyGrantingTicketStorageClass if it supports encryption. |
No |
cipherAlgorithm |
The algorithm used by the proxyGrantingTicketStorageClass if it supports encryption. Defaults to DESede |
No |
millisBetweenCleanUps |
Startup delay for the cleanup task to remove expired tickets from the storage. Defaults to 60000 msec |
No |
ticketValidatorClass |
Ticket validator class to use/create | No |
hostnameVerifier |
Hostname verifier class name, used when making back-channel calls | No |
privateKeyPath |
The path to a private key to decrypt PGTs directly sent encrypted as an attribute | No |
privateKeyAlgorithm |
The algorithm of the private key. Defaults to RSA |
No |
如果設定了 acceptAnyProxy 或 allowedProxyChains 引數,則會創建 Cas30ProxyTicketValidator;否則創建不支持代理票據的 Cas30ServiceTicketValidator,
2.4、配置 HttpServletRequestWrapperFilter(可選)
包裝 HttpServletRequest 的過濾器,getRemoteUser 和 getPrincipal 方法會回傳與 CAS 相關的物體資訊,在 web.xml 增加如下配置:
<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>
該過濾器的引數說明如下:
| Property | Description | Required |
|---|---|---|
roleAttribute |
Used to determine the principal role. | No |
ignoreCase |
Whether role checking should ignore case. Defaults to false |
No |
2.5、配置 AssertionThreadLocalFilter(可選)
該過濾器把登錄資訊放入 ThreadLocal 中,可以通過 org.jasig.cas.client.util.AssertionHolder 來獲取用戶資訊(AssertionHolder.getPrincipal()),這在無法使用 HttpServletRequest 時很有用,在 web.xml 增加如下配置:
<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>
2.6、配置 ErrorRedirectFilter(可選)
該過濾器用于發生例外時,重定向到指定的地址,在 web.xml 增加如下配置:
<filter> <filter-name>CAS Error Redirect Filter</filter-name> <filter-class>org.jasig.cas.client.util.ErrorRedirectFilter</filter-class> <init-param> <param-name>java.lang.Exception</param-name> <param-value>/yourapp/error.jsp</param-value> </init-param> <init-param> <param-name>defaultErrorRedirectPage</param-name> <param-value>/yourapp/defaulterror.jsp</param-value> </init-param> </filter> <filter-mapping> <filter-name>CAS Error Redirect Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
該過濾器的引數說明如下:
| Property | Description | Required |
|---|---|---|
defaultErrorRedirectPage |
Default url to redirect to, in case no error matches are found. | Yes |
java.lang.Exception |
Fully qualified exception name. Its value must be redirection url | No |
2.7、單點登出(可選)
2.7.1、單點登錄服務端配置
在 WEB-INF\classes\application.properties 檔案,增加如下配置:
#允許登出后跳轉到指定頁面 cas.logout.followServiceRedirects=true #登出后重定向地址的引數名 cas.logout.redirectParameter=service #登出后默認的重定向地址 #cas.logout.redirectUrl=http://127.0.0.1:9090 #登出時是否彈出確認框 cas.logout.confirmLogout=false #是否移除子系統的票據 cas.logout.removeDescendantTickets=true #是否禁用單點登出 #cas.slo.disabled=true #是否默認異步通知客戶端清除session cas.slo.asynchronous=false
2.7.2、單點登錄客戶端配置
單點登出客戶端需要配置一個 SingleSignOutFilter 和一個 ContextListener,SingleSignOutFilter 需要配置在其他過濾器的最前面,在 web.xml 增加如下配置:
<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> <init-param> <param-name>logoutCallbackPath</param-name> <param-value>http://127.0.0.1:9090/cas_client_tomcat_war_exploded/test.jsp</param-value> </init-param> </filter> <filter-mapping> <filter-name>CAS Single Sign Out Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
SingleSignOutFilter 過濾器的引數說明如下:
| Property | Description | Required |
|---|---|---|
artifactParameterName |
The ticket artifact parameter name. Defaults to ticket |
No |
logoutParameterName |
Defaults to logoutRequest |
No |
relayStateParameterName |
Defaults to RelayState |
No |
eagerlyCreateSessions |
Defaults to true |
No |
artifactParameterOverPost |
Defaults to false |
No |
logoutCallbackPath |
The path which is expected to receive logout callback requests from the CAS server. This is necessary if your app needs access to the raw input stream when handling form posts. If not configured, the default behavior will check every form post for a logout parameter. | No |
2.8、撰寫測驗頁面
這里寫個簡單的 JSP,在頁面中獲取用戶的資訊(web.xml 中需配置 HttpServletRequestWrapperFilter 和 單點登出):
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ page import="org.jasig.cas.client.authentication.AttributePrincipal"%> <% String remoteUser = request.getRemoteUser(); AttributePrincipal principal = (AttributePrincipal)request.getUserPrincipal(); String attributes = principal.getAttributes().toString(); %> <html> <head> <title>Title</title> </head> <body> remoteUser:<%=remoteUser%> principalName:<%=principal.getName()%> principalAttributes:<%=attributes%> <br><a href="http://127.0.0.1:8080/cas/logout?service=http://127.0.0.1:9090/cas-client/index.jsp">logout</a> </body> </html>
2.9、部署 Web 應用
部署 Web 應用到 Java Web 應用服務器(如:Tomcat)中即可,
3、SpringBoot 應用接入
3.1、引入依賴
<dependency> <groupId>org.jasig.cas.client</groupId> <artifactId>cas-client-support-springboot</artifactId> <version>3.6.4</version> </dependency>
3.2、增加 CAS 相關配置
在 application.yml 中增加如下配置:
cas: server-login-url: http://127.0.0.1:8080/cas/login #cas服務端登錄地址 server-url-prefix: http://127.0.0.1:8080/cas #cas服務端地址 client-host-url: http://127.0.0.1:9090 #客戶端地址 validation-type: cas3 #驗證使用的協議 server: port: 9090
其他的可選引數如下:
cas.single-logout.enabled 是否單點登出,默認falsecas.authentication-url-patterns 與AuthenticationFilter作用類似,默認/*cas.validation-url-patterns 與TicketValidationFilter作用類似,默認/*cas.request-wrapper-url-patterns 與HttpServletRequestWrapperFilter作用類似,默認/*cas.assertion-thread-local-url-patternscas.gatewaycas.use-sessioncas.attribute-authoritiescas.redirect-after-validationcas.allowed-proxy-chainscas.proxy-callback-urlcas.proxy-receptor-urlcas.accept-any-proxyserver.context-parameters.renew
3.3、啟動類增加 @EnableCasClient
@EnableCasClient @SpringBootApplicationpublic class CasApplication {...}
3.4、撰寫測驗 Controller
package com.abc.controller; import org.jasig.cas.client.authentication.AttributePrincipal; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.HttpServletRequest; @RequestMapping("/test") @Controller public class TestController { private static Logger logger = LoggerFactory.getLogger(TestController.class); @ResponseBody @RequestMapping("/getUser") public String test1(HttpServletRequest request) { String remoteUser = request.getRemoteUser(); AttributePrincipal principal = (AttributePrincipal)request.getUserPrincipal(); return "remoteUser=" + remoteUser + ",principalName=" + principal.getName() + ",principalAttributes=" + principal.getAttributes(); } }
啟動應用后訪問:http://127.0.0.1:9090/test/getUser,登錄后頁面回傳用戶相關資訊,
4、CAS 客戶端集群接入
如果客戶端是集群的話,可以使用 Spring Session 來實作同一型別的各客戶端節點的 Session 共享;前端使用代理服務器來代理,
4.1、集群創建
Spring Session 的使用可參考:https://www.cnblogs.com/wuyongyin/p/11775849.html,這里就不詳述了,假設使用上面的 SpringBoot 應用來組建集群:
| 地址 | 說明 |
| http://127.0.0.1:9090 | 節點1 |
| http://127.0.0.1:9091 | 節點2 |
| http://127.0.0.1:9092 | 代理地址 |
啟動節點1:
java -Dcas.client-host-url=http://127.0.0.1:9092 -Dserver.port=9090 -jar cas-client-springboot-1.0.0.jar
啟動節點2
java -Dcas.client-host-url=http://127.0.0.1:9092 -Dserver.port=9091 -jar cas-client-springboot-1.0.0.jar
配置 nginx 代理:
upstream cas { server 127.0.0.1:9090 weight=1; server 127.0.0.1:9091 weight=1; #ip_hash; } server { listen 9092; server_name localhost; location / { proxy_pass http://cas; } }
啟動 ngxin 并訪問代理地址:http://127.0.0.1:9092/test/getUser,
4.2、集群單點登出
使用 Spring Session 后,單點登出客戶端的 Session 還是存在的,可能是 CAS 客戶端還不能和 Spring Session 結合使用,處理方法:
1、先呼叫客戶端的一個請求,在該請求中使用 Session 失效:
@ResponseBody @RequestMapping("/logout") public String logout(HttpSession session) { session.invalidate(); return "logout success"; }
2、再訪問單點登出的地址 http://127.0.0.1:8080/cas/logout?service=http://127.0.0.1:9092/test/getUser,
CAS 客戶端接入的詳細說明可參考官網說明:https://github.com/apereo/java-cas-client,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/474790.html
標籤:Java
上一篇:Spring事務原始碼解讀
下一篇:JavaWeb環境配置
