以下内容轉自:http://www.qqread.com/java/2007/11/w381156.html
本文介紹了單點登陸(SSO, Single Sign On)的實作原理,詳細地解釋了單點登陸的實作原理以及實作過程中的關鍵點和相關選項的含義,并且通過Josso與JBoss伺服器的內建,簡要介紹了在JBoss環境中單點登陸的實施。
随着網際網路的不斷發展,各種網絡化應用服務的不斷普及,在大中型企業中,使用者可能每天需要登入到許多不同的資訊應用系統,如協同辦公系統、郵件系統、檔案關系系統、各種網絡化的應用服務等。而每個系統都要求擁護遵循它們所定義的一套安全政策,比如要求輸入使用者名和密碼。随着使用者所擁有的服務的不斷增多,使用者登陸所帶來的出錯可能性便會随之增加,資訊受到非法截獲和破壞的可能性也會增大,系統的安全性就會相應降低。同時對于系統管理者來說他除了要管理使用者的使用者名和密碼之外,還需要對不同的使用者進行相應安全政策的設定。這樣就勢必造成了系統和安全管理資源的開銷,降低了生産效率,同時還增加了企業IT部門的管理成本。為了解決以上的問題,現在很多企業在進行資訊化實施的過程中引入了單點登陸,就是先通過一個應用程式的安全驗證後,再通路其他應用中的受保護資源時,不再需要重新登入驗證。當然,要求該使用者使用的使用者名和密碼在通路的應用中一緻,且擁有足夠權限。下面我們将通過Josso與JBoss的內建的單點登陸(SSO)的執行個體,對單點登陸(SSO)的原理及其在JBoss環境下的技術實作進行更進一步的分析。
1. 什麼是單點登陸(SSO)
單點登入(SSO,Single Sign On)是指在分布式環境下,整個系統隻有一個可以登入進入的點,它對所有的請求(Request)都是通用的。單點登入可以保證使用者能夠通路到可以通路的資源,如果有一個未被授權的請求要求通路被保護的資源,這個請求将自動被導向到相應的驗證點進行登入驗證。
2. 單點登入(SSO)的實作原理
(1) 登陸點。理想的情況是使用者通過任何應用系統都能進行登陸,而且效果一樣。這種單一的登陸點在整個系統的設計中是唯一認證使用者的地方,由登陸點将相應的使用者資訊傳遞給應用系統,應用系統利用這些資訊來進行使用者的驗證。
(2) 應用系統的單點登入(SSO)內建。并不是任何系統都能夠使用SSO,隻有那些符合SSO規範,使用SSO API的應用系統才具有SSO的功能。簡單地說就是要修改已有的應用系統,屏蔽已有的應用系統的使用者認證子產品,使用系統提供的SSO API來驗證使用者,以及對使用者的操作進行授權。
(3) 統一的認證,權限資訊庫。通常SSO要求有統一的認證,權限存放庫。但現實中,有的系統無法使用外部的認證,授權資訊庫,是以就需要在應用系統和SSO認證系統之間進行認證,同時進行授權資訊的資料同步。
實作描述:在使用者成功通過SSO認證系統認證之後,系統提供的映射授予權限來為使用者登入到其有權可以使用的應用系統。系統提供的映射取消使用者權限來實作使用者的登出功能。
使用者存取由SSO認證系統所提供的安全政策,SSO會話服務儲存了對使用者授權的證明,這樣就不再需要使用者重新進行身份驗證。在這種方式下,使用者就擁有了通路通過SSO應用系統內建的應用服務的權限,我們提供的SSO Session将會為它保持會話服務。(見圖1)

圖1 SSO登陸過程
同時,SSO應用系統還包括的與登入恰恰相反的,統一的登出點,即使用者登出,就失去了應用系統內建的應用服務的通路權限。(見圖2)
圖2 SSO登出過程
3. Josso與JBoss內建的單點登入(SSO)環境的搭建
(1)、部署環境的準備及配置。
在搭建單點登陸(SSO)開發環境之前,需要準備的開發工具有:
JDK1.5.04 (http://java.sun.com)
JBoss 4.0.4GA (http://www.jboss.org)
josso-1.4.tar (http://www.josso.org)
MySQL 5.0和MySQL的JDBC驅動mysql-connector-java-3.1.13-bin.jar (http://www.mysql.org)
需要設定的環境有:
JAVA_HOME = C:\Program Files\Java\jdk1.5.0_09
JBOSS_HOME = D:\JBoss4.0.5GA
JOSSO_HOME = D:\josso1.4
(2)、定義使用者模型和安全政策。這裡我們采用JAAS的使用者模型進行資料模型的設計(如圖3)。
同時,向資料庫裡添加一些資料。以上操作的SQL腳本另見附件createdb.sql。
(3)、配置Josso的SSO gateway。在src\resources下可以見到josso-gateway-config.xml,修改其中的設定,原檔案中有關于JDBC,DataSource,LDAP等配置的模版,這裡我們設定最簡單的JDBC連接配接資料庫進行認證,需要修改的有JDBC Credential Store和JDBC Credential Store。詳細修改的檔案見附件
JOSSO_USER : 使用者的登陸驗證資訊
JOSSO_ROLE : 儲存所有可定義的使用者角色
JOSSO_USER_ROLE : 儲存每個使用者與角色關聯的資訊
JOSSO_USER_PROPERTY : 儲存使用者的個人資訊
josso-gateway-config.xml。
<!-- ========================================================= --> <!-- JDBC Credential Store --> <!-- ========================================================= --> <credential-store> <class>org.josso.gateway.identity.service.store.db.JDBCIdentityStore</class> <credentialsQueryString> SELECT login AS username , password AS password FROM josso_user WHERE login = ? </credentialsQueryString> <connectionName>root</connectionName> <connectionPassword>123456</connectionPassword> <connectionURL>jdbc:mysql://localhost:3306/josso_exam</connectionURL> <driverName>com.mysql.jdbc.Driver</driverName> </credential-store> <!-- ========================================================= --> <!-- JDBC Identity Store --> <!-- ========================================================= --> <sso-identity-store> <class> org.josso.gateway.identity.service.store.db.JDBCIdentityStore </class> <userQueryString> SELECT login FROM josso_user WHERE login = ? </userQueryString> <rolesQueryString> SELECT josso_role.name FROM josso_role , josso_user_role , josso_user WHERE josso_user.login = ? AND josso_user.login = josso_user_role.login AND josso_role.name = josso_user_role.name </rolesQueryString> <userPropertiesQueryString> SELECT 'user.description' AS name , description AS value FROM josso_user WHERE login = ? UNION SELECT name AS name , value AS value FROM josso_user_property WHERE login = ? </userPropertiesQueryString> <connectionName>root</connectionName> <connectionPassword>123456</connectionPassword> <connectionURL>jdbc:mysql://localhost:3306/josso_exam</connectionURL> <driverName>com.mysql.jdbc.Driver</driverName> </sso-identity-store>
(4)、将MySQL的驅動拷貝到/src/webapp/josso/WEB-INF/lib目錄下,供JDBC連接配接資料庫時調用。
(5)、配置Josso的登陸點和登出點,在josso-agent-config.xml中修改,這裡我們保持Josso系統預設的登陸和登出設定,同時注意應當把<endpoint>選項的localhost改為主機相對應的IP位址,否則SSO将會失效。
(6)、進入指令行模式,轉到Josso的主目錄下,執行build.bat war、build.bat install-jboss4和build.bat deploy-jboss4即可。
(7)、修改JBoss server\default\conf目錄下的login-config.xml檔案,在裡面添加Josso的login模型。
<application-policy name = "josso"> <authentication> <login-module code = "org.josso.jb4.agent.JBossSSOGatewayLoginModule" flag = "required"> <module-option name="debug">true</module-option> </login-module> </authentication> </application-policy>
(8)、修改JBoss server/default/deploy/jbossweb-tomcat55.sar目錄下的server.xml檔案,在其中添加<Value>選項和<Realm>選項。
<Valve className="org.josso.tc55.agent.SSOAgentValve" debug="1"/> <Realm className="org.josso.jb4.agent.JBossCatalinaRealm" appName="josso" userClassNames="org.josso.gateway.identity.service.BaseUserImpl" roleClassNames="org.josso.gateway.identity.service.BaseRoleImpl" debug="1" />
(9)、啟動JBoss。在浏覽器中輸入http://localhost:8080/partnerapp/protected,如果能轉到登陸界面,然後輸入使用者名(user1)和密碼(user1pwd)能夠進行登陸,那麼Josso和JBoss單點登陸(SSO)的內建就大功告成了。
4. Josso與Web應用安全政策的管理
Josso在Web應用安全政策的管理主要通過JBoss容器的進行使用者權限的配置設定和取消。它的整個應用模型主要是基于JAAS的安 全政策模型進行拓展,并對Web頁面層和EJB應用元件分别進行安全控制,下面我們通過Josso自帶的一個例子來說明。
Web頁面層的安全控制是在web.xml中通過<login-config>、<security-constraint>和<security-role>标簽定義來實作的。
以下是Josso中partnerapp例子對Web頁面層的安全控制實作:
<security-constraint> <!-- Sample Security Constraint --> <web-resource-collection> <!-- We're going to protect this resource and make it available only to users in "role1". --> <web-resource-name>public-resources</web-resource-name> <url-pattern>/resources/*</url-pattern> <http-method>HEAD</http-method> <http-method>GET</http-method> <http-method>POST</http-method> <http-method>PUT</http-method> <http-method>DELETE</http-method> </web-resource-collection> </security-constraint> <security-constraint> <web-resource-collection> <web-resource-name>protected-resources</web-resource-name> <url-pattern>/josso/*</url-pattern> <url-pattern>/protected/*</url-pattern> <http-method>HEAD</http-method> <http-method>GET</http-method> <http-method>POST</http-method> <http-method>PUT</http-method> <http-method>DELETE</http-method> </web-resource-collection> <auth-constraint> <role-name>role1</role-name> </auth-constraint> <user-data-constraint> <transport-guarantee>NONE</transport-guarantee> </user-data-constraint> </security-constraint> <login-config> <auth-method>FORM</auth-method> <form-login-config> <form-login-page>/login-redirect.jsp</form-login-page> <form-error-page>/login-redirect.jsp</form-error-page> </form-login-config> </login-config> <security-role > <description>Role 1</description> <role-name>role1</role-name> </security-role>
對于EJB應用元件隻需在ejb-jar.xml的部署描述符中添加<security-role>中定義相應的安全政策,對于JBoss來說同時還需要在jboss.xml中添加<security-domain>,以保證目前域的安全政策生效。在partnerapp中的實作如下:
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE ejb-jar PUBLIC '-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN' 'http://java.sun.com/dtd/ejb-jar_2_0.dtd'> <ejb-jar> <display-name>Partner Component</display-name> <enterprise-beans> <session> <ejb-name>PartnerComponentEJB</ejb-name> <home>org.josso.samples.ejb.PartnerComponentHome</home> <remote>org.josso.samples.ejb.PartnerComponent</remote> <ejb-class>org.josso.samples.ejb.PartnerComponentEJB</ejb-class> <session-type>Stateless</session-type> <transaction-type>Container</transaction-type> </session> </enterprise-beans> <assembly-descriptor> <security-role> <description>Role 1</description> <role-name>role1</role-name> </security-role> <method-permission> <description>Security attributes for 'PartnerComponenttEJB' methods</description> <role-name>role1</role-name> <method> <ejb-name>PartnerComponentEJB</ejb-name> <method-name>*</method-name> </method> </method-permission> <container-transaction> <method> <ejb-name>PartnerComponentEJB</ejb-name> <method-name>*</method-name> </method> <trans-attribute>Required</trans-attribute> </container-transaction> </assembly-descriptor> </ejb-jar> <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE jboss PUBLIC "-//JBoss//DTD JBOSS 3.0//EN" "http://www.jboss.org/j2ee/dtd/jboss_3_0.dtd"> <jboss> <security-domain>java:/jaas/josso</security-domain> <enterprise-beans> <session> <ejb-name>PartnerComponentEJB</ejb-name> <jndi-name>josso/samples/PartnerComponentEJB</jndi-name> </session> </enterprise-beans> </jboss>
以上是Josso對Web應用層和EJB元件所關聯的安全政策的部署描述,另外在Josso驗證的驗證過程中,登陸頁面、登出頁面和通過驗證後使用者的資訊都是通過JBoss伺服器支援的單點登陸模式來實作的。JBoss伺服器支援的登入驗證機制主要有:基于HTTP的基本驗證(采用簡單的Base64編碼),基于HTTPS的用戶端驗證(采用證書驗證),基于表單驗證(通過表單送出的資訊,自己定制驗證方式)等;而通過驗證後的使用者資訊可以通過Servlet的request對象的getUserPrincipal()方法來獲得。在這裡我們就不多做介紹。相關的資訊可以查閱JBoss及Servlet的文檔。
5. 小結
單點登陸(SSO)是一個很大的議題,在本文中筆者隻是簡單地通過對單點登陸(SSO)的實作原理和Josso在JBoss環境下的實施的介紹,讓讀者在一個側面對單點登陸(SSO)有一定認識。