實現Web應用程序的安全機制是Web應用程序的設計人員和編程人員必須面對的任務。在J2EE中,Web容器支持應用程序內置的安全機制。
Web應用程序的安全機制有二種組件:認證和授權。基於J2EE的Web容器提供三種類型的認證機制:基本認證、基於表單的認證、相互認證。由於能夠對認證用戶界面進行定制,大多數的Web應用程序都使用基於表單的認證。Web容器使用在Web應用程序的部署描述符中定義的安全角色對應用程序的Web資源的訪問進行授權。
在使用基於表單的認證機制中,應用程序的設計人員和開發人員會遇到3類問題:
·基於表單的認證如何與數據庫和LDAP等其他領域的安全機制協同工作。(這是非常必要的,因為許多組織已經在數據庫和LDAP表單中實現了認證機制。)
·如何在Web應用程序的部署描述符(web.xml)中增加或刪除軍政府的授權角色。
·Web容器在Web資源層次上進行授權;應用程序則需要在單一的Web資源中執行功能層次上的授權。
盡管有許多與基於表單的認證有關的文檔和例子,但都沒有能夠闡明這一問題。因此,大多數的應用程序都以自己的方式襀安全機制。
本篇文章說明了基於表單的認證如何與其他方面的安全機制,尤其是數據庫中的安全機制協作的問題。它還解釋了Web窗口如何使用安全角色執行授權以及應用程序如何擴展這些安全角色,保護Web資源中的功能。
基於表單的認證
基於表單的認證能夠使開發人員定制認證的用戶界面。web.xml的login-config小節定義了認證機制的類型、登錄的URI和錯誤頁面。
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/login.jsp</form-login-page>
<form-error-page>/fail_login.html</form-error-page>
</form-login-config>
</login-config>
登錄表單必須包含輸入用戶姓名和口令的字段,它們必須被分別命名為j_username和j_password,表單將這二個值發送給j_security_check邏輯名字。
下面是一個該表單如何在HTML網頁中實現的例子:
<form method="POST" action="j_security_check">
<input type="text" name="j_username">
<input type="password" name="j_password">
</form>
除非所有的連接都是在SSL上實現的,該表單能夠透露用戶名和口令。當受保護的Web資源被訪問時,Web容器就會激活為該資源配置的認證機制。
為了實現Web應用程序的安全,Web容器執行下面的步驟:
1、在受保護的Web資源被訪問時,判斷用戶是否被認證。
2、如果用戶沒有得到認證,則通過重定向到部署描述符中定義的注冊頁面,要求用戶提供安全信任狀。
3、根據為該容器配置的安全領域,確認用戶的信任狀有效。
4、判斷得到認證的用戶是否被授權訪問部署描述符(web.xml)中定義的Web資源。
象基本的安全認證機制那樣,在Web應用程序的部署描述符中,基於表單的認證不指定安全區域。也就是說,它不明確地定義用來認證用戶的安全區域類型,這就會在它使用什麼樣的安全區域認證用戶方面引起混淆。
要對用戶進行驗證,Web窗口需要完成下面的步驟:
1、判斷該容器配置的安全區域。
2、使用該安全區域進行認證。
由於數據庫和LDAP在維護信息方面提供了更大的靈活性,因此大多數組織都會希望繼續使用它們維護安全認證和授權信息。
許多Web窗口都支持不同類型的安全區域:數據庫、LDAP和定制區域。例如,在Tomcat Web容器中,server.xml將數據庫配置為其安全區域。
<Realm
className="org.apache.catalina.realm.JDBCRealm"
debug="99"
driverName="oracle.jdbc.driver.OracleDriver"
connectionURL="jdbc:oracle:thin:@{IPAddress}:{Port}:{Servicename}"
connectionName="{DB Username}"
connectionPassword="{Password}"
userTable="users"
userNameCol="username"
userCredCol="password"
userRoleTable="user_roles"
roleNameCol="rolename"
/>
Tomcat的server.xml的<Realm>標志定義了窗口用來識別一個用戶的安全區域的類型。注意,容器對Web應用程序使用該區域,應用程序的認證機制是基於表單的。
授權
一旦用戶被識別後,容器就會得到認證用戶的安全角色,看用戶是否屬於在部署描述符中的<auth-constraint>標志中定義的安全角色之一。如果用戶不屬於任何一個安全角色,則容器會返回一個錯誤。
部署描述符(web.xml)的<security-constraint>標志定義了被保護的Web資源和能夠訪問這些資源的安全角色清單。
<security-constraint>
<web-resource-collection>
<web-resource-name>AdminPages</web-resource-name>
<description> accessible by authorised users </description>
<url-pattern>/admin/*</url-pattern>
<http-method>GET</http-method>
</web-resource-collection>
<auth-constraint>
<description>These are the roles who have access</description>
<role-name>manager</role-name>
</auth-constraint>
</security-constraint>
Web窗口在網頁層次上執行認證。然而,商業性應用程序可能還希望對一個網頁內的功能進行認證,這會要求在應用程序中定義一些新的附加的與應用程序有關的安全角色。為了控制對功能的訪問,應用程序需要理解角色的權限概念。Web容器標准沒有解決權限的問題。
由於授權角色是動態的,開發人員常常會感到迷惑,即這些安全角色是否需要添加到部署描述符中。為了使應用程序充分利用安全支持,Web容器只需要在部署描述符中定義的一個角色。因此,應用程序可以定義一個高層次的角色,然後將所有的用戶都指派給該角色。這將使該角色中的所有用戶都擁有能夠訪問Web資源的權限。
另外,應用程序還可以定義額外的角色,執行對一種Web資源中較低層次的功能的授權。由於應用程序已經配置有一個包含應用程序中所有用戶的高層次安全角色,這些低層次的安全角色也就不需要在部署描述符中進行定義。這使得Web應用程序能夠利用容器的授權支持,實現與指定應用程序有關的授權。
我們可以在部署描述符中為所有用戶定義一個高層次的管理員角色,保護管理類Web資源,這使得管理員角色中的所有用戶都能夠訪問管理網頁。為了控制管理網頁中的其他功能,我們可以在應用程序中創建 sysadmin或appadmin等新的角色。
應用程序可以對這些安全角色進行擴展,使它們擁有一定的權限。然後,應用程序可以使用這些權限來控制對其功能的訪問。
盡管與特定應用程序相關的安全角色不是定義在部署描述符中的,這些角色仍然可以在isUserInRole方法中使用,判斷用戶是否在這些安全角色中。
優點
·Web應用程序無需實現認證機制,簡化Web應用程序的配置。
·Web應用程序能夠使用getRemoteUser、IsUserInRole和getUserPrincipal方法實現有規劃的安全。
·Web應用程序能夠將認證信息傳播給EJB容器。
在Tomcat中配置數據庫安全區域
1、創建用戶表。
該數據庫表需要有username和password二個字段。
create table users (username varchar(20) not null, password(20) not null)
2、創建角色表
該表維護著應用程序中角色的清單,它僅僅有rolename一個字段。
create table roles (rolename varchar(20) not null)
3、創建用戶-角色關聯表
該表維護著一個用戶和各個角色之間的關聯,一個用戶可以屬於一個或多個角色。
create table user_roles (username varchar(20) not null, rolename varchar(20) not null)
4、在表中插入數據
insert into users values('user1', 'password')
insert into role values('manager')
insert into user_roles values('user1', 'manager')
5、創建用戶表。
該數據庫表需要有username和password二個字段。
create table users (username varchar(20) not null, password(20) not null)
6、創建角色表
該表維護著應用程序中角色的清單,它僅僅有rolename一個字段。
create table roles (rolename varchar(20) not null)
7、創建用戶-角色關聯表
該表維護著一個用戶和各個角色之間的關聯,一個用戶可以屬於一個或多個角色。
create table user_roles (username varchar(20) not null, rolename varchar(20) not null)
8、在表中插入數據
insert into users values('user1', 'password')
insert into role values('manager')
insert into user_roles values('user1', 'manager')
9、通過將下面的信息拷貝到{tomcat}\conf\文件夾的server.xml文件中,配置Tomcat。(本例使用了薄客戶端驅動程序,Tomcat使用內存區域作為缺省的安全區域。)
<Realm
className="org.apache.catalina.realm.JDBCRealm"
debug="99"
driverName="oracle.jdbc.driver.OracleDriver"
connectionURL="jdbc:oracle:thin:@{IP address}:{Port}:{Servicename}"
connectionName="{DB Username}"
connectionPassword="{Password}"
userTable="users"
userNameCol="username"
userCredCol="password"
userRoleTable="user_roles"
roleNameCol="rolename"
/>
用環境變量替換下面的值:
{IP Address} ━━數據庫服務器的IP地址
{Port} ━━端口號
{Servicename} ━━服務名字
{DB Username} ━━數據庫登錄
{Password} ━━數據庫登錄的口令
10、將Oracle的薄客戶機驅動程序JAR文件或數據庫的JDBC驅動程序拷貝到{tomcat_home}/server/lib目錄中。
11、用下面的安全約束配置Web應用程序的部署描述符
<security-constraint>
<web-resource-collection>
<web-resource-name>Protected Area</web-resource-name>
<!-- 定義需要被保護的URL -->
<url-pattern>/*</url-pattern>
<http-method>DELETE</http-method>
<http-method>GET</http-method>
<http-method>POST</http-method>
<http-method>PUT</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>manager</role-name>
</auth-constraint>
<user-data-constraint><transport-guarantee>
NONE</transport-guarantee></user-data-constraint>
</security-constraint>
<!-- 缺省的登錄配置使用基於表單的認證 -->
<login-config>
<auth-method>FORM</auth-method>
<realm-name>Example Form-Based Authentication Area</realm-name>
<form-login-config>
<form-login-page>/jsp/login.jsp</form-login-page>
<form-error-page>/jsp/error.jsp</form-error-page>
</form-login-config>
</login-config>
需要注意的是,<auth-constraint>中<role-name>的值應當是用戶-角色關聯表中中角色之一。
在Tomcat中配置例子文件
1、使用上面介紹的命令配置Tomcat。
2、下載security-form-based.war文件,並將它拷貝到Tomcat的webapps目錄。
3、啟動Tomcat服務器
4、打開一個浏覽器,輸入下面的地址:http://{ip address:port no}/security-form-based/protected/index.jsp
5、輸入用戶名和口令。
在WebLogic中配置數據庫安全區域
配置Web應用程序的部署描述符,這一過程與在Tomcat中配置非常相似。Tomcat和WebLogic的配置描述符之間的一個差別是,WebLogic配置描述符要求下面的小節,而Tomcat不需要下面的小節:
<security-role>
<description>
Manager security role
</description>
<role-name>
manager
</role-name>
</security-role>
結論
通過本篇文章,讀者應該會對基於表單的認證、以及它如何與數據庫安全區域配合進行認證有個比較深刻的認識。Web應用程序能夠利用基於表單的認證機制,保護它的資源,同時允許使用以前的安全認證機制。
另外,本篇文章還描述了J2EE Web提供的授權支持層次,以及在不修改Web應用程序的部署描述符的情況下如何定義新的安全角色。