CAS單點登入(SSO)介紹及部署
介紹
CAS
CAS 是Yale(耶魯)大學的一個開源的企業級單點登入系統,它的特點:
- Java (Spring Webflow/Spring Boot) 服務元件
- 可插拔身份驗證支援(LDAP,Database,X.509,MFA)
- 支援多種協議(CAS,SAML,OAuth,OpenID,OIDC)
- 跨平臺客戶端支援(Java,.Net,PHP,Perl,Apache等)
- 與uPortal,Liferay,BlueSocket,Moodle,Google Apps等整合
CAS提供了一個友好的開源社群,方便開發者積極支援和貢獻專案。
知識擴充套件
SSO
單點登入(Single Sign On),簡稱為 SSO,是目前比較流行的企業業務整合的解決方案之一。SSO的定義是在多個應用系統中,使用者只需要登入一次就可以訪問所有相互信任的應用系統。
業務流程
當用戶第一次訪問應用系統A的時候,因為還沒有登入會被引導到認證系統中進行登入;根據使用者提供的登入資訊,認證系統進行身份校驗,如果通過校驗,應該返回給使用者一個認證的憑據(ticket);使用者再訪問別的應用的時候,就會將這個ticket帶上,作為自己認證的憑據,應用系統接受到請求之後會把ticket送到認證系統進行校驗,檢查ticket的合法性。如果通過校驗,使用者就可以在不用再次登入的情況下訪問應用系統B和應用系統C了。
認證系統功能要求
- 所有應用系統共享同一個身份認證系統
- 統一的認證系統是SSO的前提之一。認證系統的主要功能是將使用者的登入資訊和使用者資訊庫相比較,對使用者進行登入認證;認證成功後,認證系統應該生成統一的認證標誌(ticket)並立即返還給使用者。另外,認證系統還應該對ticket進行效驗,判斷其有效性。
- 所有應用系統能夠識別和提取ticket資訊
- 要實現SSO的功能,讓使用者只登入一次,就必須讓應用系統能夠識別已經登入過的使用者。應用系統應該能對ticket進行識別和提取,通過與認證系統的通訊,能自動判斷當前使用者是否登入過,從而完成單點登入的功能。
OAuth 2.0
OAuth是一個關於授權(authorization)的開放網路標準,在全世界得到廣泛應用,目前的版本是2.0版。
業務流程
OAuth在“客戶端”與“服務提供商”之間設定了一個授權層(authorization layer)。“客戶端”不能直接登入“服務提供商”,只能登入授權層,以此將使用者與客戶端區分開來。“客戶端”登入授權層所用的令牌(token),與使用者的密碼不同。使用者可以在登入的時候,指定授權層令牌的許可權範圍和有效期。
“客戶端”登入授權層以後,“服務提供商”根據令牌的許可權範圍和有效期,向“客戶端”開放使用者儲存的資料。
總結
通過上面的概述大家可以很清楚的想明白兩者的適用場景,以面向的使用者不同可以做個劃分,sso服務物件是各個應用系統,oauth服務物件是使用者。
入門
架構
系統元件
CAS系統架構包括CAS Server和CAS Clients,它們是通過各種協議進行通訊的兩個物理元件。
CAS Server
CAS Server是基於Spring框架構建的Java Servlet,其主要職責是通過發出和驗證票證來驗證使用者並授予對使用CAS的服務(通常稱為CAS客戶端)的訪問許可權。當用戶在伺服器上登入時向會向用戶發出票證(TGT)並建立SSO會話。通過使用TGT令牌進行瀏覽器重定向,根據使用者的請求向服務發出服務票證(ST)。隨後通過反向通道通訊在CAS伺服器上驗證ST。這些業務流程在CAS協議文件中非常詳細地描述。
CAS Clients
“CAS Client”在具體使用中有兩個不同的含義,CAS Client是可以通過所支援的協議與伺服器通訊的任何啟用CAS的應用程式,CAS Client還可以是可以與各種軟體平臺和應用整合以便經由某種認證協議(例如,CAS,SAML,OAuth)與CAS Server通訊的軟體包。客戶端支援多種軟體平臺和應用的CAS客戶端已經開發。
- 平臺
- Apache httpd Server (mod_auth_cas module)
- Java (Java CAS Client)
- .NET (.NET CAS Client)
- PHP (phpCAS)
- Perl (PerlCAS)
- Python (pycas)
- Ruby (rubycas-client)
- 應用
- Outlook Web Application (ClearPass + .NET CAS Client)
- Atlassian Confluence
- Atlassian JIRA
- Drupal
- Liferay
- uPortal
支援的協議
客戶端通過幾種支援的協議與伺服器通訊。所有支援的協議在概念上類似,但不同的協議對應於特定的應用場景。例如,CAS協議支援委託(代理)認證,SAML協議支援屬性釋放和單點退出。
- 支援的協議
- CAS (versions 1, 2, and 3)
- SAML 1.1 and 2
- OpenID Connect
- OpenID
- OAuth 2.0
示例
部署
要想讓CAS服務跑起來,具體的安裝方式有很多,在這裡只是演示我的方式,給大家一個參考。
安裝要求
- java oracle jdk 1.8以上
- tomcat7以上
- maven3.x
- gradle2.x
關於上面元件的安裝過程就不在這裡展開,大家安裝有疑問可以先到網上搜索,也可以加群與我聯絡。
下載安裝包
你可以直接從github上下載這個專案 https://github.com/apereo/cas-gradle-overlay-template
,也可以直接訪問下載連結 https://github.com/apereo/cas-gradle-overlay-template/archive/master.zip
。
有人可能好奇為什麼要下載這個專案?原因在於我們要覆蓋官方安裝包中預設的屬性,這也是官方提供的一個示例專案。
這個專案體積非常小,因為它依賴的jar包需要下載,這也就是為什麼我要安裝Maven的原因,但又由於這個專案包是由gradle來構建的,所以還需要安裝Gradle。
終端操作
接下來大家跟著我的命令執行,應該會有相同的結果。
下載專案
cd /usr/local/src
wget -c https://github.com/apereo/cas-gradle-overlay-template/archive/master.zip
unzip master.zip
# 你應該看到和我相同的目錄
├── cas-gradle-overlay-template
│ ├── LICENSE
│ ├── README.md
│ ├── build.gradle
│ ├── cas
│ ├── etc
│ ├── gradle
│ ├── gradle.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
編譯專案並下載依賴包
進入專案根目錄,後續的命令除特別說明外都將在這個目錄下執行。
cd cas-gradle-overlay-template
在執行構建命令時會從遠端地址下載 gradle-3.3-bin.zip
壓縮包(下載速度慢,並且中斷之後不會增量下載),所以我建議你通過旋風之類的軟體把這個檔案下載並放到下面的目錄裡面。
gradle
└── wrapper
├── gradle-3.3-bin.zip
├── gradle-wrapper.jar
└── gradle-wrapper.properties
如果你像我上面說的那樣做,那還別忘記要修改 gradle-wrapper.properties
檔案,把原來的遠端地址替換成相對地址即可。
vim gradle-wrapper.properties
distributionUrl=gradle-3.3-bin.zip
另外我建議你在maven中設定遠端倉庫地址為國內的源,因為這樣下載速度會非常快,國外的倉庫下載jar包太慢。國內的源裡面推薦使用阿里的源,下面貼上一段示例程式碼。
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
現在執行命令開始下載專案所需要的依賴包,並構建一個新的war包,我們會部署這個包以啟動CAS服務。
./gradlew clean build
確保你在專案要目錄下執行上面的命令,如果成功你會看到和我類似的結果
Copying configuration to /etc/cas/config
:cas:clean
:cas:compileJava UP-TO-DATE
:cas:processResources UP-TO-DATE
:cas:classes UP-TO-DATE
:cas:findMainClass
:cas:copyConfig
:cas:war
:cas:bootRepackage SKIPPED
:cas:assemble
:cas:compileTestJava UP-TO-DATE
:cas:processTestResources UP-TO-DATE
:cas:testClasses UP-TO-DATE
:cas:test UP-TO-DATE
:cas:check UP-TO-DATE
:cas:build
BUILD SUCCESSFUL
實際的結果可能和我不相同,因為我並非首次執行上面的命令,專案所依賴的包已經下載完了,所以你執行命令的時間可能比我要長。
上面的命令主要是為了讓你下載專案的依賴jar包,雖然實際上我們的war包已經生成,但還沒有配置一些引數以覆蓋官方包中的預設引數,所以現在還得修改配置檔案。具體介紹請繼續往下看。
生成證書
由於CAS服務全程使用HTTPS加密通訊協議,所以必須配置證書以達到此目的,否則服務將不會正常服務。
不管你是從證書管理網站上申請的證書,還是像下面示例的這樣,是自己生成的未簽名證書,都可以按照下面的方法進行證書的配置。
第一步:生成key
openssl genrsa -des3 -out cas.example.com.key
第二步:根據上一步的key生成crt證書
openssl req -new -x509 -key cas.example.com.key -out cas.example.com.crt
第三步:根據前面兩步的檔案生成PKCS12證書
openssl pkcs12 -export -in cas.example.com.crt -inkey cas.example.com.key -out cas.example.com.p12 -name cas
第四步:把P12證書匯入java的金鑰儲存庫檔案中
keytool -importkeystore -deststorepass 123456 -destkeypass 123456 -destkeystore keystore -srckeystore cas.example.com.p12 -srcstoretype PKCS12 -srcstorepass 123456 -alias cas
最後一步操作之後會在當前目錄生成一個檔案 keystore
,你需要將這個檔案複製到專案的配置檔案目錄下面。
mv keystore etc/cas/config/
-rw-r--r-- 1 xxx xxx 1.1K 2 18 17:17 etc/cas/config/keystore
引數配置
vim etc/cas/config/cas.properties
修改檔案之後的內容示例
cas.server.name: https://cas.example.com:8443
cas.server.prefix: https://cas.example.com:8443/cas
cas.adminPagesSecurity.ip=127\.0\.0\.1
logging.config: file:/etc/cas/config/log4j2.xml
# Embedded Tomcat
server.ssl.keyStore: file:/etc/cas/config/keystore
server.ssl.keyStorePassword=123456
server.ssl.keyPassword=123456
# Accept Users Authentication
cas.authn.accept.users=
# Ticket Granting Cookie
cas.tgc.signingKey=Ci1kE5-PyQfD0i_a3sH16B32QhwGBbHXOmhR4r36vv0cB0RasLdEb7AI0ykouyMrE5RBbIAxqXvipmQEUA6juQ
cas.tgc.encryptionKey=Zv0LARlN7g7LxI6wmp6T4sLr2-TiZZ3K5W8pRIWcvO0
# Spring Webflow
cas.webflow.signing.key=16ua53AWy3PM4rYj6V0rBab_U-X7HvnFpDAVaXMEwwdhiZzTHM5vlYpLzm8HR6jf4DcDbM1_HQxCu6kQGjAOqg
cas.webflow.encryption.key=NamwVAyVrXeyrKvs
儘量按照上面的示例配置來修改,以免你掉進未知的“坑”裡面。由於修改了配置檔案,需要重新執行上面的命令以構建專案。
部署到容器
由於專案中使用了Spring boot,按照官方文件的描述是可以按照以下的命令進行啟動的,但我在操作時每次都構建到80%左右終端上的命令就停止了。所以我選擇直接將war包部署到tomcat中。
如果你使用Spring boot則使用下面的命令:
./gradlew bootRun
如果你使用tomcat則按照如下步驟操作:
- 假設你安裝了tomcat
- 把war包部署到webapps目錄中
cp cas/build/libs/cas.war /opt/tomcat/webapps/
- 啟動tomcat
/opt/tomcat/bin/startup.sh
- 查詢日誌輸出
18-Feb-2017 17:19:32.000 資訊 [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["http-nio-8080"]
18-Feb-2017 17:19:32.026 資訊 [main] org.apache.tomcat.util.net.NioSelectorPool.getSharedSelector Using a shared selector for servlet write/read
18-Feb-2017 17:19:32.029 資訊 [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["https-jsse-nio-8443"]
18-Feb-2017 17:19:32.411 資訊 [main] org.apache.tomcat.util.net.NioSelectorPool.getSharedSelector Using a shared selector for servlet write/read
18-Feb-2017 17:19:32.412 資訊 [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["ajp-nio-8009"]
結束
配置本地hosts讓 cas.example.com
域名指向本地IP 127.0.0.1
,開啟瀏覽器訪問 https://cas.example.com:8443/cas
可以看到下面的頁面。
寫到這裡關於CAS的安裝就結束了,至於將CAS與具體的業務系統結合,那是屬於下節文章的內容,請關照我後續關於CAS的系列文章。