在JSP和servlet開發的應用程式中,Web開發人員可以使用幾種機制來保護應用程式。資源通過在應用程式部署描述符中標識它們並向其分配角色來以聲明方式進行保護。
有幾個級別的身份驗證可用,從使用識別字和密碼的基本身份驗證到使用證書的複雜身份驗證。
基於角色的認證
servlet規範中的認證機制使用了一種稱為基於角色的安全性技術。這個做法是,不是在用戶級別限制資源,而是創建角色並通過角色限制資源。
可以在檔tomcat-users.xml
中定義不同的角色,tomcat-users.xml
位於Tomcat的主目錄conf
中。此檔的示例如下所示 -
<?xml version = '1.0' encoding = 'utf-8'?>
<tomcat-users>
<role rolename = "tomcat"/>
<role rolename = "role1"/>
<role rolename = "manager"/>
<role rolename = "admin"/>
<user username = "tomcat" password = "tomcat" roles = "tomcat"/>
<user username = "role1" password = "tomcat" roles = "role1"/>
<user username = "both" password = "tomcat" roles = "tomcat,role1"/>
<user username = "admin" password = "secret" roles = "admin,manager"/>
</tomcat-users>
此檔定義了用戶名,密碼和角色之間的簡單映射。請注意,給定的用戶可能有多個角色; 例如,username =“both”
有兩個角色:“tomcat”
角色和“role1”
角色。
當確定並定義了不同的角色,就可以通過使用WEB-INF
目錄中web.xml
檔中的<security-constraint>
元素,將基於角色的安全限制放在不同的Web應用程式資源上。
以下是web.xml中的示例元素項 -
<web-app>
...
<security-constraint>
<web-resource-collection>
<web-resource-name>SecuredBookSite</web-resource-name>
<url-pattern>/secured/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<description>
Let only managers use this app
</description>
<role-name>manager</role-name>
</auth-constraint>
</security-constraint>
<security-role>
<role-name>manager</role-name>
</security-role>
<login-config>
<auth-method>BASIC</auth-method>
</login-config>
...
</web-app>
以上元素項將意味著 -
- 對與
/secured/*
匹配的URL的任何HTTP GET或POST請求將受到安全限制。 - 具有
manager
角色的人員可獲得安全資源。 login-config
元素用於描述BASIC認證形式。
如果嘗試流覽包含/security
目錄的任何URL,將顯示以下對話框,要求輸入用戶名和密碼。 如果提供了用戶:admin
和密碼:secrer
,那麼可以訪問與/secured/*
匹配的URL,因為我們已將用戶管理員定義為允許訪問該資源的manager
角色。
基於表單的認證
使用表單身份驗證方法時,必須提供登錄表單以提示用戶輸入用戶名和密碼。 以下是login.jsp
的簡單代碼。 這有助於為同一目的創建一個表單 -
<html>
<body bgcolor = "#ffffff">
<form method = "POST" action ="j_security_check">
<table border = "0">
<tr>
<td>Login</td>
<td><input type = "text" name="j_username"></td>
</tr>
<tr>
<td>Password</td>
<td><input type = "password" name="j_password"></td>
</tr>
</table>
<input type = "submit" value = "Login!">
</form>
</body>
</html>
在這裏,必須確保登錄表單中有包含名為:j_username
和j_password
的表單元素。 <form>
標籤中的操作必須是j_security_check
。必須用作表單方法: POST
。 同時,還需要修改<login-config>
標籤,將auth-method
指定為FORM
-
<web-app>
...
<security-constraint>
<web-resource-collection>
<web-resource-name>SecuredBookSite</web-resource-name>
<url-pattern>/secured/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<description>Let only managers use this app</description>
<role-name>manager</role-name>
</auth-constraint>
</security-constraint>
<security-role>
<role-name>manager</role-name>
</security-role>
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/login.jsp</form-login-page>
<form-error-page>/error.jsp</form-error-page>
</form-login-config>
</login-config>
...
</web-app>
現在當嘗試訪問URL /secured/*
任何資源時,將顯示上述表單,詢問用戶ID和密碼。 當容器看到j_security_check
操作時,它使用一些內部機制來認證調用者。
如果登錄成功並且呼叫者被授權訪問受保護的資源,則容器使用會話ID從該點起為調用者標識登錄會話。容器使用包含session-id
的cookie維護登錄會話。 伺服器將cookie發送回客戶端,只要主調用方後續請求者提供該cookie,容器將知道調用者是誰。
如果登錄失敗,則伺服器返回通過表單錯誤頁面設置標識的頁面
這裏,j_security_check
是使用表單登錄的應用程式必須為登錄表單指定的操作。 同樣的形式,還應該有一個名為j_username
的文本輸入控件和一個名為j_password
的密碼輸入控件。當看到這個,這意味著表單中包含的資訊將被提交到伺服器,這將檢查名稱和密碼。 這是如何完成的是伺服器特定的。
檢查標準領域實現,以瞭解j_security_check
如何用於Tomcat容器。
Servlet/JSP中的程式安全性
HttpServletRequest
對象提供以下方法,可用於在運行時挖掘安全資訊 -
編號 | 方法 | 描述 |
---|---|---|
1 | String getAuthType() |
getAuthType() 方法返回一個String 對象,該對象表示用於保護Servlet的認證方案的名稱。 |
2 | boolean isUserInRole(java.lang.String role) |
isUserInRole() 方法返回一個布爾值:如果用戶處於給定角色,則返回true ,否則返回false 。 |
3 | String getProtocol() |
getProtocol() 方法返回一個String對象,表示用於發送請求的協議。可以檢查該值以確定是否使用安全協議。 |
4 | boolean isSecure() |
isSecure() 方法返回一個布爾值,表示是否使用HTTPS進行請求。值設置為true 意味著它是和連接是安全的。 值設置為false 表示請求不是安全的。 |
5 | Principle getUserPrinciple() |
getUserPrinciple() 方法返回一個java.security.Principle 對象,該對象包含當前已驗證用戶的名稱。 |
例如,對於鏈接到管理員的頁面的JSP,可以使用以下代碼 -
<% if (request.isUserInRole("manager")) { %>
<a href = "managers/mgrreport.jsp">Manager Report</a>
<a href = "managers/personnel.jsp">Personnel Records</a>
<% } %>
通過檢查用戶在JSP或Servlet中的角色,可以自定義該頁面,僅向用戶顯示可以訪問的專案。 如果需要在認證表單中輸入用戶名,可以在請求對象中調用getRemoteUser()
方法。