摘要
CAS Server Cas Client Pac4j
什么是單點登錄
單點登錄(Single Sign On)奄喂,簡稱 SSO铐殃,常用于多個系統(tǒng)中,用戶只需登錄一次跨新,就可以訪問其他信任的系統(tǒng)富腊。比如,員工登錄過OA系統(tǒng)后域帐,可以直接訪問郵件系統(tǒng)赘被,而不再需要登錄郵件系統(tǒng)。這里的OA系統(tǒng)和郵件系統(tǒng)俯树,可以認(rèn)為是相互信任的子系統(tǒng)帘腹,他們共用一套用戶數(shù)據(jù),這套用戶數(shù)據(jù)的權(quán)限認(rèn)證由統(tǒng)一的認(rèn)證服務(wù)器來認(rèn)證许饿。
CAS協(xié)議
現(xiàn)階段比較流行的單點登錄解決方案是CAS(Central Authentication Service)阳欲,官網(wǎng)中有如下說明
Enterprise Single Sign-On - CAS provides a friendly open source community that actively supports and contributes to the project. While the project is rooted in higher-ed open source, it has grown to an international audience spanning Fortune 500 companies and small special-purpose installations.
CAS
提供了CAS協(xié)議來完成單點登錄,主要流程如下
用戶第一次向瀏覽器訪問應(yīng)用1(https://app.example.com)陋率,應(yīng)用1判斷用戶沒有登錄球化,重定向到CAS server(https://cas.example.com/cas/login?service=https://app.example.com)
CAS server中判斷當(dāng)前用戶的sso的session不存在,展示用戶名密碼輸入框
用戶輸入用戶名密碼向CAS server登錄瓦糟,驗證通過后筒愚,CAS server 生成sso的session,向瀏覽器設(shè)置cookie菩浙,CASTGC=TGT-...
其中cookie的值就是sso中session的key巢掺。同時CAS server會對應(yīng)用1生成一個ticket句伶,再去重定向到應(yīng)用1中,應(yīng)用1拿到這個ticket再次請求CAS server獲取授權(quán)數(shù)據(jù)陆淀。成功后考余,設(shè)置cookie,jessionid=...轧苫。到此楚堤,應(yīng)用1第一次認(rèn)證結(jié)束。當(dāng)應(yīng)用1第二次認(rèn)證的時候直接校驗jessionid是否合法即可含懊。
當(dāng)應(yīng)用2第一次訪問的時候身冬,同樣會重定向到CAS server中去,只不過岔乔,此時酥筝,由于,應(yīng)用1已經(jīng)認(rèn)證通過了重罪,同時sso的session已經(jīng)保存了樱哼,所以,CAS server不會再去要求用戶登錄剿配,而是直接對應(yīng)用2生成一個ticket,后面的邏輯就和前面一樣了阅束。
代碼演示
下面的代碼都可以在cas-pac4j-example下載
本機環(huán)境說明
- jdk 1.8
- maven 3.6.3
- mysql 5.7.29
- cas server 5.3.14
- cas client 3.6.1
- shiro 1.5.3
- pac4j 4.0.3
cas服務(wù)端
直接clone官方提供的overlaygit clone https://github.com/apereo/cas-overlay-template.git
由于最新版6.3.x需要jdk11的支持呼胚,所以切換了5.3的分支
添加了src/main/resources/目錄,在改目錄下創(chuàng)建了application.properties文件和services目錄息裸,用于cas server的自定義認(rèn)證方式蝇更。
由于認(rèn)證數(shù)據(jù)依賴數(shù)據(jù)庫,請先運行sql文件呼盆,更改application.properties的數(shù)據(jù)庫連接信息年扩。
修改pom文件,添加如下依賴
<dependency>
<groupId>org.apereo.cas</groupId>
<artifactId>cas-server-support-rest</artifactId>
<version>${cas.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<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>
命令行運行mvn clean package & java -jar target/cas.war
等待服務(wù)啟動后访圃,訪問http://locahost:8443/cas厨幻,會跳轉(zhuǎn)登錄,輸入u/p登錄成功腿时。到此况脆,cas服務(wù)端算是ok了。
cas客戶端
新建spring boot項目cas-client2
和cas-client3
批糟,其中cas-client2的端口為8082格了,cas-client3的端口為8083,pom中添加如下依賴
<dependency>
<groupId>org.jasig.cas.client</groupId>
<artifactId>cas-client-support-springboot</artifactId>
<version>${cas.client.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
添加注解@EnableCasClient
啟用casClient徽鼎,application中添加如下cas服務(wù)配置
cas.server-url-prefix=http://localhost:8443/cas
cas.server-login-url=${cas.server-url-prefix}/login
cas.client-host-url=http://localhost:${server.port}
啟動客戶端cas-client2和cas-client3盛末,訪問http://localhost:8082弹惦,會跳轉(zhuǎn)cas登錄,然后在訪問http://localhost:8083悄但,會發(fā)現(xiàn)已經(jīng)認(rèn)證通過棠隐,不會跳轉(zhuǎn)cas登錄,達(dá)到了單點登錄的效果算墨。
客戶端shiro集成cas服務(wù)認(rèn)證
現(xiàn)實的系統(tǒng)中可能不是像上面那樣簡單的配置宵荒,可能客戶端先前已經(jīng)集成了shiro等權(quán)限框架,后面再接入cas認(rèn)證净嘀,這種情況怎么處理呢报咳?
新建spring boot項目cas-client1
pom中添加入下依賴
<dependency>
<groupId>io.buji</groupId>
<artifactId>buji-pac4j</artifactId>
<version>${buji.version}</version>
</dependency>
<dependency>
<groupId>org.pac4j</groupId>
<artifactId>pac4j-cas</artifactId>
<version>${pac4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-web-starter</artifactId>
<version>${shiro.version}</version>
</dependency>
application.properties的配置如下
server.port=8081
cas.server-url-prefix=http://localhost:8443/cas
cas.server-login-url=${cas.server-url-prefix}/login
cas.client-host-url=http://localhost:${server.port}
cas.client-name=app-client1
shiro.loginUrl=/login.html
主類中CasClient1Application
添加了cas認(rèn)證的相關(guān)配置,而TestController
則包含了單純的shiro登錄和cas的rest方式登錄挖藏。
啟動后暑刃,訪問http://localhost:8081/cas.html,會跳轉(zhuǎn)到CAS Server去認(rèn)證膜眠,認(rèn)證完成后岩臣,訪問http://localhost:8081/test可以測試權(quán)限數(shù)據(jù)是否正確,CAS Server除了采用CAS本身的login登錄界面外宵膨,還支持rest的方式架谎,獲取認(rèn)證,訪問http://localhost:8081/login.html辟躏,輸入u/p后會通過rest的方式認(rèn)證谷扣。