-
導出證書(1和2步驟是找了課程,隨便寫了一下存記錄,不過對於自己測試不投入使用應該不影響)
C:\Users\Ddlm2>keytool -genkey -alias testcas -keystore D:/testcas -storepass 123456 -keyalg RSA -validity 3650 您的名字與姓氏是什么? [Unknown]: test 您的組織單位名稱是什么? [Unknown]: test 您的組織名稱是什么? [Unknown]: test 您所在的城市或區域名稱是什么? [Unknown]: test 您所在的省/市/自治區名稱是什么? [Unknown]: test 該單位的雙字母國家/地區代碼是什么? [Unknown]: test CN=test, OU=test, O=test, L=test, ST=test, C=test是否正確? [否]: Y 輸入 <testcas> 的密鑰口令 (如果和密鑰庫口令相同, 按回車): 再次輸入新口令: Warning: JKS 密鑰庫使用專用格式。建議使用 "keytool -importkeystore -srckeystore D:/testcas -destkeystore D:/testcas -deststoretype pkcs12" 遷 移到行業標准格式 PKCS12。 C:\Users\Ddlm2>keytool -genkey -alias testcas -keystore D:/testcas -storepass 123456 -keyalg RSA -validity 3650 -export -trustcacerts -file D:/testcas.cer 存儲在文件 <D:/testcas.cer> 中的證書 Warning: JKS 密鑰庫使用專用格式。建議使用 "keytool -importkeystore -srckeystore D:/testcas -destkeystore D:/testcas -deststoretype pkcs12" 遷 移到行業標准格式 PKCS12。 -
導入jdk的證書庫
C:\Users\Ddlm2>keytool -import -trustcacerts -alias testcas -file D:/testcas.cer 輸入密鑰庫口令: 再次輸入新口令: 所有者: CN=test, OU=test, O=test, L=test, ST=test, C=test 發布者: CN=test, OU=test, O=test, L=test, ST=test, C=test 序列號: 429f9b95 生效時間: Fri Aug 13 11:15:22 CST 2021, 失效時間: Mon Aug 11 11:15:22 CST 2031 證書指紋: SHA1: 3A:20:B4:25:12:96:6E:EB:F7:15:15:BE:11:A7:C5:66:60:25:D6:A8 SHA256: 06:80:FC:34:63:27:20:ED:6E:74:CB:51:2B:5B:86:E0:70:C2:CD:65:36:46:52:13:25:0A:B4:9B:7F:67:31:B7 簽名算法名稱: SHA256withRSA 主體公共密鑰算法: 2048 位 RSA 密鑰 版本: 3 擴展: #1: ObjectId: 2.5.29.14 Criticality=false SubjectKeyIdentifier [ KeyIdentifier [ 0000: 24 05 3F B0 42 A4 02 84 70 D1 F2 09 4A AB D8 93 $.?.B...p...J... 0010: 8B 29 85 BB .).. ] ] 是否信任此證書? [否]: y 證書已添加到密鑰庫中注:需要在tomcat的server.xml中配置證書。
不過自己測試,只會提示密碼泄露不安全什么的,無大礙。
-
下載 cas server 安裝包,這里使用的是5.3。下面的鏈接都可以使用
https://github.com/apereo/cas-overlay-template/tree/5.3 ---------------------------------------- https://wwa.lanzoui.com/b010pvygd 密碼:casserver -
打war包。 安裝maven的環境變量(或者導入idea打包),在cas-overlay-template-5.3目錄打開cmd命令行使用
mvn package進行打包,會在target目錄下出現cas.war文件。 -
部署tomcat。 將本地tomcat服務器拷貝出來一份,作為cas服務器,將war包復制到webapps下面。運行tomcat,war包會自動解壓到car文件夾中。
注:如果cas使用5以上,tomcat必須8以上。
-
端口映射。 在tomcat目錄下的conf目錄下的server.xml中添加
<Connector port="8332" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> <!-- 意為將8332接口轉到8443接口 --> <!-- 8332是對外的,那么8443呢,cas默認端口就是8443,applicaion.properties中的第5行左右 -->注:主要為了防止端口號沖突,都可以任意修改。
-
添加http協議。 webapps\cas\WEB-INF\classes\services下的HTTPSandIMAPS-10000001.json的第三行修改成
"serviceId" : "^(https|http|imaps)://.*",使其接受http協議。 -
也可以自定義用戶名。 webapps\cas\WEB-INF\classes下的application.properties 最后那里
cas.authn.accept.users=casuser::Mellon是默認的用戶名和密碼,可以修改為自己喜歡的。
然后再添加:cas.tgc.secure=false cas.serviceRegistry.initFromJson=true -
重啟tomcat, 訪問
localhost:8332/cas/login輸入7步驟中的賬號密碼進行測試。
接下來整理,springboot整合cas client。cas服務器端返回數據在下面。
-
新建maven或者springboot項目都可以,打開pom文件添加依賴。
<dependencies> <!-- cas的客戶端 --> <dependency> <groupId>net.unicon.cas</groupId> <artifactId>cas-client-autoconfig-support</artifactId> <version>2.2.0-GA</version> <exclusions> <exclusion> <groupId>org.jasig.cas.client</groupId> <artifactId>cas-client-core</artifactId> </exclusion> </exclusions> </dependency> <!-- 使用更高版本的cas-client-core --> <dependency> <groupId>org.jasig.cas.client</groupId> <artifactId>cas-client-core</artifactId> <version>3.5.0</version> </dependency> <!-- 故意降的版本 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.1.3.RELEASE</version> </dependency> </dependencies>注:若啟動時候報錯,且去掉cas相關東西又可以正常啟動。可以嘗試降一下你自己的springboot版本。
-
添加啟動類,切記
@EnableCasClientimport net.unicon.cas.client.configuration.EnableCasClient; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * @author ddlm * @date 2021/08/17 10:53 */ @EnableCasClient @SpringBootApplication public class CASClientOne { public static void main(String[] args) { SpringApplication.run(CASClientOne.class, args); } } -
添加配置,這里使用的yml,properties就是:變.和=而已。
server: port: 9101 cas: # cas服務器端的地址和端口,注意端口號。 server-url-prefix: http://localhost:8332/cas server-login-url: http://localhost:8332/cas/login # 本地的地址,用於回調回來 client-host-url: http://localhost:9101 # 需要攔截的地址(所有為"/*"),可配置數組 authentication-url-patterns: - "/auth/login" - "/auth/createOrder" validation-type: CAS3注:攔截的接口是個例子。因為使用場景場景不同:全由cas控制或者只需要登錄在自己項目控制。
如果服務端不需要關,只需要使用cas實現單點登錄,且獲取數據,如果從session中獲取,需要配置中開啟一下:
cas: use-session: true,對應獲取數據就request.getSession().getAttribute("key"); -
隨便寫個接口測試。
@RestController public class TestController { @RequestMapping("/testFirst") public String TestMethod() { return "This is First Method."; } }注:確保url在配置中的攔截范圍內。
-
為了方便對比,再新建一個項目,步驟一致,起碼接口名、端口名和返回內容修改一下。
-
啟動兩個項目,訪問第一個項目中的接口,需要登錄,登錄后。
-
訪問第二個項目的接口,此時不需要登錄即為成功。
-
擴展: 一些博客中,結合了攔截器進行匹配,這個看需要進行添加,主要是可以忽略接口,加幾層一般都可以避免,如果使用過濾器注意與配置的交集。
@Configuration public class CASConfig { @Value("${cas.server-url-prefix}") private String serverUrlPrefix; @Value("${cas.server-login-url}") private String serverLoginUrl; @Value("${cas.client-host-url}") private String clientHostUrl; @Value("${ignore-host-url}") private String ignoreHostUrl; /** * 授權過濾器 */ @Bean public FilterRegistrationBean filterAuthenticationRegistration() { FilterRegistrationBean registration = new FilterRegistrationBean(); registration.setFilter(new AuthenticationFilter()); // 設定匹配的路徑 registration.addUrlPatterns("/*"); Map<String,String> initParameters = new HashMap<>(); initParameters.put("casServerLoginUrl", serverUrlPrefix); initParameters.put("serverName", clientHostUrl); //忽略的url,"|"分隔多個url initParameters.put("ignorePattern", ignoreHostUrl); registration.setInitParameters(initParameters); // 設定加載的順序 registration.setOrder(1); return registration; } }其中
ignore-host-url需要另外在yml中配置。
接下來配置cas服務器從數據庫中獲取用戶名和密碼,並返回該人員所有信息(只是測試使用)。
-
獲取登錄名。為什么多返回更多內容呢,因為用戶名默認會返回,這里介紹獲取用戶名的三種方法。
request.getRemoteUser(); ((Assertion) request.getSession().getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION)).getPrincipal().getName(); 第二步不getName(),getAttributes();在得到的集合中去get("username"),大概,可以打印出來找一下。注:從request中能get到的都get過來了,然后轉成json輸出找到的...
-
CAS服務器配置連接數據庫。
我測試時候是重新打包的,也可以參考這位大佬的博客tomcat8搭建cas服務器,使用MYSQL數據庫
或者這位大佬的:cas5.3.1 從搭建到連接mysql(簡而優美),是直接復制jar包進來,不需要重新打包的。
添加需要訪問數據庫的依賴,在
cas-overlay-template-5.3/pom.xml<dependency> <groupId>org.apereo.cas</groupId> <artifactId>cas-server-support-jdbc</artifactId> <version>${cas.version}</version> </dependency> <dependency> <groupId>org.apereo.cas</groupId> <artifactId>cas-server-support-jdbc-drivers</artifactId> <version>${cas.version}</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <!-- 與數據庫版本一致 --> <version>8.0.23</version> </dependency>注:切記最后面那個版本號一定一定一定要跟自己mysql的版本一致。可百度查看如何查看MySQL版本。
小版本號也要保證一致!!!
-
打包,部署,重新按照服務器的部署修改一下。
-
修改 webapps\cas\WEB-INF\classes下的application.properties最后部分,注釋掉默認或者自定義的賬號密碼:
# cas.authn.accept.users=casuser::Mellon添加:
cas.authn.jdbc.query[0].url=jdbc:mysql://localhost:3306/cas_server_demo?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&serverTimezone=Asia/Shanghai cas.authn.jdbc.query[0].principalAttributeList=id,username,password,stunumber,stuclass cas.authn.jdbc.query[0].user=root cas.authn.jdbc.query[0].password=123456 cas.authn.jdbc.query[0].sql=select id,username,password,stu_number as stuNumber,stu_class as stuClass from student where username=? cas.authn.jdbc.query[0].fieldPassword=password # cas.authn.jdbc.query[0].driverClass=com.mysql.jdbc.Driver cas.authn.jdbc.query[0].driverClass=com.mysql.cj.jdbc.Driver # 忽略https安全協議,使用 HTTP 協議 cas.tgc.secure=false # 是否開啟json識別功能,默認為false cas.serviceRegistry.initFromJson=true # 指明路徑 cas.serviceRegistry.json.location=classpath:/services注:
- principalAttributeList中是返回的字段名,如果想要定義別名,需要在sql中使用as重新命名。
- 注意mysql版本號與driverClass的對應。
- 未涉及密碼加密。
- 當不需要定義別名時候,sql可以直接select *
- 見網上說數據庫字段名帶下划線返回不回來,經過測試可以返回,如果失敗定義別名可解決。
-
修改webapps\cas\WEB-INF\classes\services\HTTPSandIMAPS-10000001.json,最后添加:
{ "@class" : "org.apereo.cas.services.RegexRegisteredService", "serviceId" : "^(https|http|imaps)://.*", "name" : "HTTPS and IMAPS", "id" : 10000001, "description" : "This service definition authorizes all application urls that support HTTPS and IMAPS protocols.", "evaluationOrder" : 10000, "attributeReleasePolicy" : { "@class" : "org.apereo.cas.services.ReturnAllAttributeReleasePolicy" } }添加attributeReleasePolicy,注意json格式,上面要添加
, -
准備MySQL數據庫數據
/* Navicat Premium Data Transfer Source Server : localMysql Source Server Type : MySQL Source Server Version : 80023 Source Host : localhost:3306 Source Schema : cas_server_demo Target Server Type : MySQL Target Server Version : 80023 File Encoding : 65001 Date: 17/08/2021 13:56:44 */ SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for student -- ---------------------------- DROP TABLE IF EXISTS `student`; CREATE TABLE `student` ( `id` int(0) NOT NULL AUTO_INCREMENT, `username` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL, `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL, `stu_number` int(0) NULL DEFAULT NULL, `stu_class` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of student -- ---------------------------- INSERT INTO `student` VALUES (1, 'admin', 'admin', 222222424, '234'); INSERT INTO `student` VALUES (2, 'test1', 'test1', 123454321, '235'); SET FOREIGN_KEY_CHECKS = 1; -
重啟tomcat,注意啟動日志。
-
springboot cas client取數據,我整理了一個簡易工具類。
import org.jasig.cas.client.authentication.AttributePrincipal; import org.jasig.cas.client.util.AbstractCasFilter; import org.jasig.cas.client.validation.Assertion; import javax.servlet.http.HttpServletRequest; import java.util.Map; public class CASUtil { private static HttpServletRequest request; /** * 從cas中獲取用戶名 * * @param request Http請求 * @return 登錄cas服務器的用戶名 */ public static String getAccountNameFromCas(HttpServletRequest request) { CASUtil.request = request; Assertion assertion = (Assertion) request.getSession().getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION); if (assertion != null) { AttributePrincipal principal = assertion.getPrincipal(); return principal == null ? null : principal.getName(); } else { return null; } } /** * 從cas返回值中獲取內容 * * @param request Http 請求 * @param attr 需要獲取值的鍵名 * @return 鍵名attr對應的值 */ public static String getAttributeFromCas(HttpServletRequest request, String attr) { CASUtil.request = request; Assertion assertion = (Assertion) request.getSession().getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION); if (assertion != null) { AttributePrincipal principal = assertion.getPrincipal(); // 一般不會為空,因為有attributes if(principal != null) { Object obj = principal.getAttributes().get(attr); return obj == null ? null : obj.toString(); } } return null; } } -
至此,完畢。
-
整理要點
- cas服務器
- 端口(server.xml)
- 連接數據庫(application.properties)
- 修改json配置文件(HTTPSandIMAPS-10000001.json)
- 連接數據庫依賴的驅動版本號
- cas與tomcat版本
- cas客戶端
- 依賴版本號(cas和springboot的)
@EnableCasClient注解- 配置文件中的cas服務器地址、本機地址和需要驗證的接口
- 通過request獲取即可
- cas服務器
-
當用戶名登錄不上時候,查看cas服務器命令行是否有異常。
-
參考:
