一、前言
近期,公司項目要與外公司項目對接;外公司CAS服務端項目,本公司業務系統作爲client端(Struts2+spring+ibatis)接入。由於,現在是演練階段,我提前學習下CAS server端與client端接入流程,並記錄下來;以免以後再次淌坑。
以本公司業務系統client端(Struts2+spring+ibatis)爲基礎演練;cas-client-core-3.4.1.jar被放在了WEB-INF/lib/下。
二、軟件準備
1.cas server下載地址:https://github.com/apereo/cas . 在releases選項卡中,可以找到各種版本。
2.cas client,可以去https://mvnrepository.com/artifact/org.jasig.cas.client/cas-client-core 下載,我選用的是3.4.1。
3.cas-server-4.0.0解壓後如圖,去modules包下找到cas-server-webapp-4.0.0.war,可以改名爲cas.war,放在tomcat/webapps下,啓動服務端。
4.關閉服務端tomcat,要做幾處修改如下:
- 新增賬號/密碼,或者可以用默認的casuser:Mellon
- 修改tomcat啓動端口不介紹了;直說cas有一個配置。
- 本地測試,不需要配置域名映射或Nginx代理。稍後會說道。
- 去除CAS的https認證。添加一個屬性設置
p:requireSecure="false"
。默認爲true,需要安全驗證,使用的是https協議。
- 在登錄頁面,註釋HTTPS提醒
- 啓動tomcat,訪問cas
三、client配置
1.之前說過,cas-client-core-3.4.1.jar被放在了WEB-INF/lib/下。
2.web.xml,
- cas的filter必須放在struts2 filter前方。
- ignorePattern:表示請求過濾白名單,只能是"正則表達式";但是,我嘗試了另一種正則,反而會影響"攔截效果";就這種管用。(在這裏感謝https://blog.csdn.net/eguid_1/article/details/73611781的作者)
- serverName:寫域名或者IP:端口號;再拼接別的沒用,我試過了;項目的ContextPath是cas server自動拼接的,如:我的serverName=http://localhost:9090,正常登陸後,自動回調爲http://localhost:9090/idauth
- 單點退出功能還未實現。注意:在加入SingleSignOutFilter時,一定要配置casServerUrlPrefix,不然無法啓動成功(╮(╯▽╰)╭ 我就遇到了,百思不得其解)。
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<!--單點退出配置的目的是在CAS server回調所有的application 進行單點登出操作的時候,需要這個Filter來實現session 清除。-->
<!-- 用於單點退出,該過濾器用於實現單點登出功能,可選配置 -->
<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>
<!--${casServerUrlPrefix}serviceValidate 注意${casServerUrlPrefix}的value的末尾"/"-->
<param-name>casServerUrlPrefix</param-name>
<param-value>http://localhost:2020/cas/</param-value>
</init-param>
</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>
<param-value>http://localhost:2020/cas/login</param-value>
<!--這裏的server是服務端的IP -->
</init-param>
<init-param>
<!--cas服務端回調配置-->
<param-name>serverName</param-name>
<param-value>http://localhost:9090</param-value>
</init-param>
<init-param>
<description>不攔截的請求</description>
<param-name>ignorePattern</param-name>
<param-value>/*.js|/*.css|/*.jpg|/*.png|/*.gif|/*.htm</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>
<!--${casServerUrlPrefix}serviceValidate 注意${casServerUrlPrefix}的value的末尾"/"-->
<param-name>casServerUrlPrefix</param-name>
<param-value>http://localhost:2020/cas/</param-value>
</init-param>
<init-param>
<!--cas服務端回調配置-->
<param-name>serverName</param-name>
<param-value>http://localhost:9090</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>
<filter>
<filter-name>Paramcheck</filter-name>
<filter-class>base.web.filter.Paramcheck</filter-class>
</filter>
<filter-mapping>
<filter-name>Paramcheck</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
<!-- 後續省略 -->
3.獲取登錄參數
Assertion assertion = AssertionHolder.getAssertion();
//其他屬性
Map<String, Object> attrMap = assertion.getAttributes();
//登錄賬號
AttributePrincipal principal = assertion.getPrincipal();
String account = principal.getName();
String attrJson = JSON.toJSONString(attrMap);
log.warn(">>>> account:" + account);
log.warn(">>>> attrJson:" + attrJson);
四、待續
- cas server--登錄驗證策略實現
- cas server--登錄成功後,自定義返回參數
- cas server--登錄首頁改造
- cas server--單點退出功能
五、參考文獻
https://blog.csdn.net/dongdong_java/article/details/22293377/
https://blog.csdn.net/wuzhong8809/article/details/84032196