iT邦幫忙

2017 iT 邦幫忙鐵人賽
DAY 29
0

前言

今天來整理一下servlet裡關於安全性的控管
及實作方式
內容為本書的ch12

Servlet四大安全性

主要內容有:
認證、授權、機密性、資料完整性
書中這部分主要都著重在認證和授權的部分

認證機制

  • 設定方式
    要設定servlet的安全機制
    一定要在裡面先進行認證

    • 1.設定tomcat-users.xml
      第一步就是要設定腳色和權限,通常實務上會設定在DB或是LDAP裡
      但這裡使用tomcat提供的tomcat-users.xml,但基於安全性只適合測試用或練習
      tomcat-users.xml在tomcat啟動時會先執行這份檔案

    tomcat-users.xml

    <role rolename="Guest"/>
    <role rolename="Member"/>
    <role username="Simen" password="123" roles="Member, Guest"/>
    
    </tomcat-users>
    
    • 2.設定DD
      DD在這裡只要宣告login-config就好
      表示啟用認證

      <login-config>
       <auth-method>BASIC</auth-method>
      </login-config>
      
  • 四種認證型式
    剛剛講到的login-config
    是認證的一種型式
    種共有四種:

    • 1.BASIC
      以base64編碼格式去做encoded,安全性較弱
    • 2.DIGEST
      使用DIGEST較安全的方式登入,但J2EE不完全支援
    • 3.CLIENT-CERT
      非常安全的機制,但需要公私鑰,通常應用在B2B
    • 4.FORM
      使用合法的HTML建立自訂表單,認證方式最不安全,也沒有提供加密方式

    除了FORM之外,其他方式是只要有設定在DD的login-config
    自動就會去實作彈出標準的表單登入
    這裡紀錄一下FORM的範例
    FORM主要透過j_security_check、j_username以及j_password
    來和container溝通

    web.xml

    <login-config>
     <auth-method>FORM</auth-method>
     <form-login-config>
      <form-login-page>/login.html</form-login-page>
      <form-error-page>/ErrorLogin.html</form-error-page>
     </form-login-config>
    </login-config>
    

    login.html

    <form action="j_security_check" method="post">
      <input type="test" name="j_username">
      <input type="password" name="j_password">
      <input type="submit" value="summit">
    </form>
    

授權

  • 授權步驟
    1.定義角色
    依照剛剛的user file(即tomcat-users.xml)
    依照設定的角色新增在DD裡面(但在這之前需要先啟用認證機制,即login-config)

    web.xml

    <security-role><role-name>Guest</role-name></security-role>
    <security-role><role-name>Member</role-name></security-role>
    

    2.定義資源/方法的存取限制
    定義角色之後,還需要定義存取的限制

     <security-constraint>
     <!--可以有多組 -->
     <web-resource-collection>
      <!-- 只是設定這個security的名稱(必要) -->
      <web-resource-name>SeruritySample</web-resource-name>
      <!-- 定義被限制的資源(至少要設定一組) -->
      <url-pattern>/Sample/page/*</url-pattern>
      <!-- 定義要套用在哪些方法(有設定的HTTP會照此權限設定) -->
      <http-method>GET</http-method>
      <http-method>POST</http-method>
     </web-resource-collection>
      <!-- 設定要開放給那些人透過URL呼叫HTTP -->
     <auth-constraint>
      <role-name>Guest</role-name>
      <role-name>Member</role-name>
     </auth-constraint>
    </security-constraint>
    </web-app>
    
    • security-constraint
      有以下幾點需要注意:
      限制的並不是source,而是HTTP的方法(某個角色透過限制的方法取得存取該資源)
      若指定了http-method,則其他沒有指定的HTTP均不受限制
      但若http-method都沒有設定,則所有的HTTP都會套用此限制

    • auth-constraint
      這邊設定那些角色要套用在前面的設定
      分成auth-constraint和role-name

      <auth-constraint>
        <role-name>Guest</role-name>
        <role-name>Member</role-name>
      </auth-constraint>
      

      role-name規則

      • 1.role-name為選用
      • 2.role-name裡面會設定要允許那些角色存取資源
      • 3.若沒有role-name元素,表示沒有任何使用者可以存取
      • 4.若設定星號代表任何人都可以存取資源
        <role-name>*</role-name>
        
      • 5.大小寫有分別

      auth-constraint有以下規則

      • 1.auth-constraint是選用的
      • 2.若沒有設定auth-constraint,代表任何人都可以存取
      • 3.若auth-constrain為空標籤,表示沒有人可以存取資源(和沒有此標籤剛好相反)
        <auth-constraint/>
        
    • 優先順序
      當有多組security-constraint時
      規則如下:

      • 1.多組設定會結合所有列出的角色
      • 2.角色名稱若有星號,不管設其它幾組,任何人都還是有權限
      • 3.只要某一組設定的auth-constrain為空標籤,表示全部的人都沒有權限
      • 4.只要某一組沒有包含auth-constrain,則代表任何人都可以存取

      有時候不開放給任何cilent的權限,目的是要只給web內部的應用程式存取
      (類似private的概念)

    • isUserlnRole()
      HttpServletRequest所提供的方法之一
      可以在servlet裡面取出所設定的角色去做客製化

      運作的方式為:

      • 1.在isUserlnRole()被呼叫以前,必須經過前面的認證
        若沒有經過驗證則回傳false
      • 2.Container會取得isUserlnRole()裡的參數,去跟request的user比對
        若比對為正確,則回傳true

      這裡提供了一個例子
      servlet.java

      if(request.isUserlnRole("admin"))
      {
      }
      

      web.xml

      <servlet>
       <security-role-ref>
       <role-name>admin</role-name>
       </security-role-ref>
      

      web.xml

      <security-role><role-name>Guest</role-name></security-role>
      

      Container取得isUserlnRole的順序為
      先找security-role-ref,再找security-role
      所以這個例子
      因為在security-role-ref就找到對應的名稱,因此不會失敗
      但若兩邊同時都有相同的設定,Container會以security-role-ref為主
      (但實際例子不會把角色名稱給hard code)

    • 宣告保護的受限制資源
      前面提到認證形式只有FORM才能客製化頁面,但又是安全性最低的
      security-constraint提供了一種以宣告的方式來實作
      讓資料保持完整性和機密性
      透過此設定,傳輸會從HTTP改成HTTPS
      只要在security-constraint下新增以下片段

      <user-data-constraint>
       <transport-guarantee>CONFIDENTIAL</transport-guarantee>
      </user-data-constraint>
      
      </security-constraint>
      

      transport-guarantee可接受三種合法值:
      1.NONE:default,資料不受保護
      2.INTEGRAL:資料不可以被更改
      3.CONFIDENTIAL:資料不可以被別人看到

      此外每個security-constraint只能有一個user-data-constraint


上一篇
[Day 28 ] web部署
下一篇
[Day 30] 完賽心得及未來目標
系列文
30 days JSP & Servlet學習紀錄 30

尚未有邦友留言

立即登入留言