CAS單點登陸(SSO)

1.概念java

CAS: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等集mysql

SSO:單點登陸簡稱爲 SSO,是目前比較流行的企業業務整合的解決方案之一。SSO的定義是在多個應用系統中,用戶只須要登陸一次就能夠訪問全部相互信任的應用系統。域,跨域,Session跨域,Nginx Session共享:分別在session,nginx中已有nginx

 

2.SSL/TLS/HTTPS之間的關係git

SSL(Secure Sockets Layer 安全套接層),爲Netscape所研發,用以保障在Internet上數據傳輸之安全,SSL通常是https的代名詞,TLS(Transport Layer Security,傳輸層安全)是在SSL3.0的基礎上發展的,繼承了SSL的優勢,都是用以保障在Internet上數據傳輸之安全,利用數據加密(Encryption)技術,可確保數據在網絡上之傳輸過程當中不會被截取及竊聽。SSL協議位於TCP/IP協議與各類應用層協議之間,爲數據通信提供安全支持。github

SSL協議可分爲兩層:web

SSL記錄協議(SSL Record Protocol):它創建在可靠的傳輸協議(如TCP)之上,爲高層協議提供數據封裝、壓縮、加密等基本功能的支持。算法

SSL握手協議(SSL Handshake Protocol):它創建在SSL記錄協議之上,用於在實際的數據傳輸開始前,通信雙方進行身份認證、協商加密算法、交換加密密鑰等。spring

 

3.HTTPS的數據的加密傳輸sql

 瀏覽器把協議版本號,支持的加密算法生成的隨機數A發送給服務器,服務器接到客戶端發送過來的加密算法後,查看自身支持的加密算法,肯定雙方後邊使用哪一種加密算法,而後把該算法和數字證書以及生成的隨機數B發給客戶端,客戶端接到服務器發送過來的證數後,獲得證書裏的非對稱加密的公鑰D,而後又生成一個隨機數C,把C和D加密後獲得的一個字符串E發給服務器。服務器接到這個字符串E後,用自身的私鑰解密獲得C,這樣服務器就集齊了 A,B,C,而後利用ABC生成對話加密密鑰 , 由於客戶端也獲得了A,B,C 這樣雙方都能進行加密解密了,至於加密解密的算法就是前面雙方交換加密方法時約定的加密算法。因此能夠看出ABC中,只有C是極難被別人獲得的,這樣保證了安全性,同時這個過程前面用到了非對稱加密,一旦加密密鑰肯定,後面其實用的都是對稱加密了。數據庫

 

4.使用java的keytool製做證書

keytool -genkeypair -alias serverkey -keypass 111111 -storepass 111111 \
    -dname "C=CN,ST=GD,L=SZ,O=vihoo,OU=dev,CN=vihoo.com" \
    -keyalg RSA -keysize 2048 -validity 3650 -keystore server.keystore

keytool用法  

-rfc" 表示以base64輸出文件,不然以二進制輸出。      

-startdate <startdate>          證書有效期開始日期/時間

-alias 實體別名(包括證書私鑰)

-certreq            生成證書請求

-changealias        更改條目的別名

-dname 指定證書擁有者信息 例如: 「CN=名字與姓氏,OU=組織單位名稱,O=組織名稱,L=城市或區域名稱,ST=州或省份名稱,C=單位的兩字母國家代碼」

-destalias <destalias>          目標別名

-ext <value>                    X.509 擴展

-exportcert         導出證書

-export 將別名指定的證書導出到文件 keytool -export -alias 須要導出的別名 -keystore 指定keystore -file 指定導出的證書位置及證書名稱 -storepass 密碼

-storetype <storetype>  密鑰庫類型

-genkeypair  生成密鑰對

-genseckey  生成密鑰

-genseckey          生成密鑰

-gencert            根據證書請求生成證書

-keystore 指定密鑰庫的名稱(產生的各種信息將不在.keystore文件中)

-keyalg 指定密鑰的算法 (如 RSA DSA(若是不指定默認採用DSA))

-keysize 指定密鑰長度

-keypass 指定別名條目的密碼(私鑰的密碼)

-validity 指定建立的證書有效期多少天

-printcertreq       打印證書請求的內容

-printcrl           打印 CRL 文件的內容

-providername <providername>    提供方名稱

-providerclass <providerclass>  提供方類名

-providerarg <arg>              提供方參數

-providerpath <pathlist>        提供方類路徑

-protected                      經過受保護的機制的口令

-importcert         導入證書或證書鏈

-importkeystore     從其餘密鑰庫導入一個或全部條目

-storepass 指定密鑰庫的密碼(獲取keystore信息所需的密碼)

-list 顯示密鑰庫中的證書信息 keytool -list -v -keystore 指定keystore -storepass 密碼

-v 顯示密鑰庫中的證書詳細信息

-file 參數指定導出到文件的文件名

-delete 刪除密鑰庫中某條目 keytool -delete -alias 指定需刪除的別 -keystore 指定keystore -storepass 密碼

-printcert 查看導出的證書信息 keytool -printcert -file yushan.crt

-keypasswd 修改密鑰庫中指定條目口令 keytool -keypasswd -alias 需修改的別名 -keypass 舊密碼 -new 新密碼 -storepass keystore密碼 -keystore sage

-storepasswd 修改keystore口令 keytool -storepasswd -keystore e:\yushan.keystore(需修改口令的keystore) -storepass 123456(原始密碼) -new yushan(新密碼)

-sigalg <sigalg>                簽名算法名稱

-import 將已簽名數字證書導入密鑰庫 keytool -import -alias 指定導入條目的別名 -keystore 指定keystore -file 需導入的證書

5.keytool實例

生成keystore

keytool -genkeypair -alias tomcat -keyalg RSA -validity 3650 -keysize 1024 -keystore H:/ajava/caskey/test.keystore

注意

cas.test.com 必須與以下保持一致

不然會出以下錯誤

No name matching localhost found

導出證書,注意-alias tomcat  與上述的別名須要一致

keytool -keystore  H:/ajava/caskey/test.keystore   -export  -file  H:/ajava/caskey/test.cer -alias  tomcat  -storepass 123456

 能夠查看詳情

keytool -list -keystore  H:/ajava/caskey/test.keystore -storepass 123456  

 打印證書

keytool -printcert -file H:/ajava/caskey/test.cer   //能夠添加-v

 

客戶端導入證書(jdk導入證書,不然java不信任會出現錯誤)

keytool -import -keystore F:\JAVA\jdk1.8\jre\lib\security\cacerts  -file  H:/ajava/caskey/cas.cer   -alias tomcat

注意:cacerts這個名字必須是cacerts,由於cacerts是java信任的證書庫(啓動時的jdk),不然會出現以下錯誤,且密碼必須是changeit。不然會出現以下錯誤

生成後綴.p12的證書

keytool -genkeypair -alias mykey  -keyalg RSA  -storetype PKCS12  -validity 3650 -keysize 1024 -keystore H:/ajava/caskey/mykey.p12

 在tomcat中使用(服務端)

<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
               maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
		       clientAuth="false" sslProtocol="TLS"
		       keystoreFile="H:/ajava/caskey/test.keystore" keystorePass="123456" />

這裏沒有采用客戶端認證

備註:

keystoreFile:第一步建立key存放的位置

keystorePass:建立證書時的密碼

truststoreFile:驗證客戶端證書的根證書

truststorePass:建立證書時的密碼

假如客戶端使用了驗證時,須要在瀏覽器導入相應的證書

 

這裏的例子沒有采用客戶端驗證

6.使用cas實現單點登陸

服務端

下載cas服務器    https://github.com/apereo/cas-overlay-template/tree/5.3

官方文檔   https://github.com/apereo/cas

添加到Idea中,修改pom,添加以下依賴,從新打包

其中比較重要的配置以下

log4j2.xml

配置日誌文件位置(這裏log4j,log4j2,logback 都差很少相似)

       <Property name="cas.log.dir" >.</Property>   
        <!-- To see more CAS specific logging, adjust this property to info or debug or run server with -Dcas.log.leve=debug -->
        <Property name="cas.log.level" >warn</Property>

web-inf下的application.properties文件,假如不肯意更改原配置,那麼能夠在src/resources先新建application.properties,根據springboot的配置文件加載原則,會優先加載src/resources下的application.properties,密碼啥的是有效的,可是application.yml,application.properties中配置的tomcat相關的配置,打成war包部署在獨立的tomcat上以後, 會失效,緣由是由於spring boot內置的tomcat,也就是說以下配置只對springboot啓動有效,這裏採用的是tomcat(因此以下都註釋了),上面已經配置了,tomcat啓動能夠採用上述介紹的方法(從新打war包)修改配置,也能夠解壓後修改配置,解壓後須要刪除war,不然每次啓動都會先解壓。

#頁面
#server.context-path=/cas
#端口
#server.port=8443
#證書的位置 .keystore文件的位置
#server.ssl.key-store=H:/ajava/caskey/test.keystore
#指定密鑰庫的密碼 -storepass
server.ssl.key-store-password=123456
#別名條目的密碼-keypass
#server.ssl.key-password=123456
#用戶名與密碼
#cas.authn.accept.users=casuser::Mellon

開啓服務端,密碼cas.authn.accept.users=casuser::Mellon

    

不使用ssl(https)那麼須要在application.properties文件中添加,文件位置\WEB-INF\classes\application.properties

#關閉https驗證
cas.tgc.secure=false

CAS 未認證受權服務須要在application.properties文件中添加

#開啓識別json文件,默認false
cas.serviceRegistry.initFromJson=true

在application.properties文件中添加cas.serviceRegistry.initFromJson=true實際是掃描json文件,serviceId表示容許匹配的地址,文件位置WEB-INF\classes\services\HTTPSandIMAPS-10000001.json

{
  //該文件能夠是多個,可是該文件名須要知足以下name+id+.json
  //加載的類,這裏必須使用這個類
  "@class" : "org.apereo.cas.services.RegexRegisteredService",
  //能匹配的url,可以匹配多個,也可使用正則,假如須要添加http,那麼編程"serviceId" : "^(https|imaps|http)://.*",,也就是運行經過的域
  "serviceId" : "^(https|imaps|http)://.*",
  //服務名
  "name" : "HTTPS and IMAPS",
  //id,惟一標識符
  "id" : 10000001,
  //描述
  "description" : "This service definition authorizes all application urls that support HTTPS and IMAPS protocols.",
  //定義多個服務器的執行順序,數字越大優先級越低
  "evaluationOrder" : 10000
}

假如serviceId不能匹配會出現沒有受權的錯誤

客戶端

https://github.com/apereo/java-cas-client   客戶端下載

 客戶端配置web.xml

<!--退出過濾器-->
    <filter>
        <filter-name>CAS Single Sign Out Filter</filter-name>
        <filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class>
        <init-param>
            <param-name>casServerUrlPrefix</param-name>
            <param-value>https://cas.test.com:8443/cas</param-value>
        </init-param>
    </filter>
    <!--退出監聽器-->
    <listener>
        <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class>
    </listener>
    <!--認證過濾器-->
    <filter>
        <filter-name>CAS Authentication Filter</filter-name>
        <filter-class>org.jasig.cas.client.authentication.AuthenticationFilter</filter-class>
     <!--沒有經過認證重定向的頁面--> <init-param> <param-name>casServerLoginUrl</param-name> <param-value>https://cas.test.com:8443/cas/login</param-value> </init-param> <init-param> <param-name>serverName</param-name> <param-value>http://localhost:9002</param-value> </init-param> </filter> <!--驗證過濾器--> <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>https://cas.test.com:8443/cas</param-value> </init-param> <init-param> <param-name>serverName</param-name> <param-value>http://localhost:9002</param-value> </init-param> <init-param> <param-name>redirectAfterValidation</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>useSession</param-name> <param-value>true</param-value> </init-param> </filter> <!-- 該過濾器負責實現HttpServletRequest請求的包裹--> <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 Single Sign Out Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>CAS Validation Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>CAS Authentication Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>CAS HttpServletRequest Wrapper Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>

測試

7. 配置數據庫密碼認證及md5加密,固然也可使用其餘方式加密。

使用JDBC與MD5

依賴

<!-- 數據庫驅動 --> 
<dependency> 
    <groupId>mysql</groupId> 
    <artifactId>mysql-connector-java</artifactId> 
    <version>5.1.21</version> 
</dependency> 

<!--jdbc認證須要添加的,這個是cas的依賴包--> 
<dependency>
     <groupId>org.apereo.cas</groupId> 
    <artifactId>cas-server-support-jdbc</artifactId> 
    <version>${cas.version}</version> 
</dependency>

在application.properties文件中可添加額配置,綠色表示必須

#Query Database Authentication 數據庫查詢校驗用戶名開始 
#查詢帳號密碼sql,必須包含密碼字段
cas.authn.jdbc.query[0].sql=select * from sys_user where username=?
#指定上面的sql查詢字段名(必須,密碼)
cas.authn.jdbc.query[0].fieldPassword=password
#指定過時字段,1爲過時,若過時不可用
cas.authn.jdbc.query[0].fieldExpired=expired
#爲不可用字段,1爲不可用,須要修改密碼
cas.authn.jdbc.query[0].fieldDisabled=disabled
#數據庫方言(hibernate的知識)
cas.authn.jdbc.query[0].dialect=
#數據庫驅動
cas.authn.jdbc.query[0].driverClass=
#數據庫鏈接
cas.authn.jdbc.query[0].url=
#數據庫用戶名
cas.authn.jdbc.query[0].user=
#數據庫密碼
cas.authn.jdbc.query[0].password=
#默認加密策略,經過encodingAlgorithm來指定算法,默認NONE不加密
cas.authn.jdbc.query[0].passwordEncoder.type=DEFAULT
cas.authn.jdbc.query[0].passwordEncoder.characterEncoding=UTF-8
cas.authn.jdbc.query[0].passwordEncoder.encodingAlgorithm=MD5
#Query Database Authentication

若密碼無加密,調整passwordEncoder.type=NONE
若密碼加密策略爲SHA,調整passwordEncoder.encodingAlgorithm=SHA
若算法爲自定義,實現org.springframework.security.crypto.password.PasswordEncoder接口,而且把類名配置在passwordEncoder.type

對密碼進行鹽值處理再加密,增長了反查難度,如上面的例子,對密碼只是簡單的加密,不一樣的賬號有可能相同的值,能判斷出密碼是一致,但經過此方案,大大增長了難度,因此安全係數也高了許多,推薦策略

#Encode Database Authentication 開始 
#加密次數
cas.authn.jdbc.encode[0].numberOfIterations=2
#該列名的值可替代上面的值,但對密碼加密時必須取該值進行處理
cas.authn.jdbc.encode[0].numberOfIterationsFieldName=
#鹽值固定列
cas.authn.jdbc.encode[0].saltFieldName=username
#靜態鹽值
cas.authn.jdbc.encode[0].staticSalt=.
cas.authn.jdbc.encode[0].sql=select * from sys_user_encode where username=?
#對處理鹽值後的算法
cas.authn.jdbc.encode[0].algorithmName=MD5
cas.authn.jdbc.encode[0].passwordFieldName=password
cas.authn.jdbc.encode[0].expiredFieldName=expired
cas.authn.jdbc.encode[0].disabledFieldName=disabled
cas.authn.jdbc.encode[0].url=
cas.authn.jdbc.encode[0].dialect=
cas.authn.jdbc.encode[0].user=sa
cas.authn.jdbc.encode[0].password=
cas.authn.jdbc.encode[0].driverClass=
#Encode Database Authentication 結束

 8. 退出

#容許發出退出控制退出後轉發url
cas.logout.followServiceRedirects=true

 退出後跳轉到指定頁面,假如只有https://ip/cas/logout,那麼會跳到註銷頁面

<a  href ="https://ip/cas/logout?service=https://demo.testcas.com/cas-server/login" />

 以下配置(不須要配置)

cas.logout.redirectParameter=service#上面a href的service的由來cas.logout.confirmLogout=false  #是否須要出現confirm窗口cas.logout.removeDescendantTickets=false  #是否須要移除Ticket
相關文章
相關標籤/搜索