JSP安全

在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_usernamej_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()方法。