《Spring Security3》第四章第四部分翻譯(Remember me後臺存儲和SSL)

將Remember me功能遷移至數據庫

    如今你可能會意識到咱們remember me功能的實現,可以在應用重啓前很好的使用,但在應用重啓時用戶的session會被丟失。這對用戶來講會不太便利,他們不該該關心JBCP Pets的維護信息。html

    幸運的是,Spring Security提供了將rememberme token持久化到任何存儲的接口o.s.s.web.authentication.rememberme.PersistentTokenRepository,並提供了這個接口的JDBC實現java

    在這裏,修改remember me的配置以持久化到數據庫是很是簡單的。Spring Security配置的解析器可以識別出<remember-me>聲明的data-source-ref新屬性併爲RememberMeServices切換實現類。讓咱們瞭解完成這個功能所須要的步驟。web

添加SQL以建立remember me schema

    咱們須要將包含指望schema定義的SQL文件放在classpath下(WEB-INF/classes中),它會與咱們在前面使用的其它啓動SQL腳本放在一塊兒。咱們將這個SQL腳本命名爲remember-me-schema.sql:算法

create table persistent_logins (
  username varchar_ignorecase(50) not null, 
  series varchar(64) primary key,
  token varchar(64) not null, 
  last_used timestamp not null);

爲嵌入式數據庫聲明添加新的SQL腳本

接下來,在dogstore-security.xml文件的<embedded-database>聲明中添加對新SQL腳本的引用:sql

<jdbc:embedded-database id="dataSource" type="HSQL">
  <jdbc:script location="classpath:security-schema.sql"/>
  <jdbc:script location="classpath:remember-me-schema.sql"/> 
  <jdbc:script location="classpath:test-users-groups-data.sql"/>
</jdbc:embedded-database>

配置remember me服務持久化到數據庫

最後咱們須要對<remember-me>聲明作一些簡單的配置修改使其指向咱們使用的data source:shell

<http auto-config="true" use-expressions="true" 
      access-decision-manager-ref="affirmativeBased">
  <intercept-url pattern="/login.do" access="permitAll"/>
  <intercept-url pattern="/account/*.do"  
             access="hasRole('ROLE_USER') and fullyAuthenticated"/>
  <intercept-url pattern="/*" access="hasRole('ROLE_USER')"/>
  <form-login login-page="/login.do" />
  <remember-me key="jbcpPetStore" token-validity-seconds="3600" 
               data-source-ref="dataSource"/>
  <logout invalidate-session="true" logout-success-url="" 
          logout-url="/logout"/>
</http>

這就是咱們全部要作的。如今,若是你重啓應用,將不會丟失以前合法用戶設置的remember me cookie。數據庫

    你可能會回憶起咱們在第三章實現的TokenBasedRememberMeServices,它用MD5哈希算法將一系列與用戶相關的數據編碼成安全的cookie,這種方式很難(但並不是不可能)篡改。express

     o.s.s.web.authentication.rememberme.PersistentTokenBasedRememberMeServices類實現了持久化tokens以及對token安全處理,它經過一個校驗方法以稍微不一樣的方式處理潛在的篡改瀏覽器

    PersistentTokenBasedRememberMeServices爲每一個用戶建立一個惟一的序列號用戶在繼續交互和認證時要使用序列號中惟一的tokens序列號和token被存儲在cookie中,在認證時要用來與存儲的token進行對比。序列號和token都是基於配置的長度隨機生成的,這使得惡意用戶成功暴力破解的可能性很小了。tomcat

    與TokenBasedRememberMeServices相似,持久化的token也可能被cookie竊取或其它的man-in-the-middle技術。在使用持久化token時,依舊建議用自定義的子類將IP地址合併到持久化token中,以及對站點的敏感區域強制使用用戶名和密碼認證。

用SSL保護你的站點

    在平常使用在線站點時,你極可能已經據說或使用過SSL。安全套接字層(SSL)協議,以及其後續的傳輸層安全(TLS),被用來爲網絡上的HTTP事務提供傳輸層的安全——它們被稱爲安全的HTTP事務(HTTPS)。

     簡而言之,SSL和TLS以一種對用戶透明的方式保護原始的HTTP傳輸數據,這些數據在客戶端瀏覽器和web服務器之間傳輸。可是做爲開發人員,在設計安全站點時,規劃使用SSL是很重要的。Spring Security提供了一系列的配置選項能夠靈活的將SSL集成到web應用中。

【儘管SSLTLS是不一樣的協議(TLS是更成熟的協議),單數大多數人更熟悉SSL這個術語,因此在本書的剩餘部分,咱們使用這個術語來代指SSLTLS兩個協議。】

詳細介紹SSL協議的機制已經超出了本書的範圍,有一些很好的書籍和技術論文很詳細地介紹了其規範和協議(你能夠從RFC:5246:傳輸安全協議(TLS)Version1.2開始,在如下地址http://tools.ietf.org/html/rfc5246

     首先且最重要的是,若是你計劃執行以下SSL相關的例子,須要配置應用服務器以支持SSL鏈接。對於Apache Tomcat,這相對很容易。若是你在使用其它的應用服務器,請查看文檔的相關部分。

生成server key store

咱們須要使用Java的keytool命令來生成一個key store。打開一個命令提示窗口,並輸入如下的命令:

keytool -genkeypair -alias jbcpserver -keyalg RSA -validity 365 
  -keystore tomcat.keystore -storetype JKS

按照提示進行以下的輸入。輸入密碼password做爲key store和我的密鑰的密碼

What is your first and last name?
  [Unknown]:  JBCP Pets Admin
What is the name of your organizational unit?
  [Unknown]:  JBCP Pets
What is the name of your organization?
  [Unknown]:  JBCP Pets
What is the name of your City or Locality?
  [Unknown]:  Anywhere
What is the name of your State or Province?
  [Unknown]:  NH
What is the two-letter country code for this unit?
  [Unknown]:  US
Is CN=JBCP Pets Admin, OU=JBCP Pets, O=JBCP Pets, L=Anywhere, ST=NH, C=US 
correct?
  [no]:  yes

這將會在當前目錄下,生成一個名爲tomcat.keystore的文件。這就是啓用Tomcat SSL所使用的key store。

【注意的是要執行的是genkeypair命令(在早於java 6的釋放版本中要使用keytoolgenkey命令)】

 爲了下一步的操做,須要記住這個文件的地址。

配置Tomcat的SSL Connector

在Apache Tomcat的conf目錄下,用XML編輯器(Eclipse或相似的均可以)打開server.xml,並取消註釋或添加SSL Connector聲明。應該以下所示:

<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
  maxThreads="150" scheme="https" secure="true"
  sslProtocol="TLS" 
  keystoreFile="conf/tomcat.keystore"
  keystorePass="password"/>

    確保在上一步中生成的tomcat.keystore文件被copy到了Tomcat安裝路徑的conf目錄下。在配置後,Tomcat服務器能夠重啓,JBCP  Pets應用可以在一個安全的端口https://localhost:8443/JBCPPets/上進行訪問。

    取決於不一樣的瀏覽器,可能須要包含https而不是http。這樣的問題可能會比較難發現,你可能會比較奇怪爲何不能看到JBCP  Pets的主頁。

    咱們假設你在對客戶的數據進行SSL保護時遇到了麻煩,你想把應用的特定部分置於SSL的保護之下。幸運的是,Spring Security讓這一切變得很簡單,只須要在<intercept-url>聲明上添加一個配置屬性

    requires-channel屬性可以添加到任何<intercept-url>聲明中,以要求全部匹配的URL要以特定的協議(HTTP,HTTPS或均可以)進行傳遞。若是按照這種形式來加強JBCP Pets站點,配置可能以下所示:

<http auto-config="true" use-expressions="true">
  <intercept-url pattern="/login.do" access="permitAll" 
                 requires-channel="https"/>
  <intercept-url pattern="/account/*.do" 
                 access="hasRole('ROLE_USER') and fullyAuthenticated" 
                 requires-channel="https"/>
  <intercept-url pattern="/*" access="permitAll" 
                 requires-channel="any"/>
  <!-- ... -->
</http>

若是此時重啓應用,你將會發現:

  1. 如今訪問登陸頁和帳號頁須要HTTPS,瀏覽器將會爲用戶自動從不安全的(HTTP)URL重定向到安全的URL。例如,嘗試訪問http://localhost:8080/JBCPPets/login.do將會被定向到https://localhost:8443/JBCPPets/login.do;

  2. 若是用戶被切換到了安全的HTTPS URL,若是他訪問一個沒必要要使用HTTPS的URL,他能繼續保留在HTTPS狀態。

    咱們能夠想象這種配置對於安全的好處——大多數的現代應用服務器使用一個secure標識session的cookie,因此強制要求登陸頁是安全的(若是這是應用的session被首次分配的地方)可以保證session的cookie可以被安全的傳輸,因此出現session劫持的可能性也更小。另外,直接將SSL加密配置在安全聲明上的作法,可以很容易的保證應用中全部敏感的頁面被適當和完整的保護。

    爲用戶自動切換適當協議(HTTP或HTTPS)的功能,經過Spring Security過濾器鏈上的另一個servlet過濾器來實現的(它的位置很靠前,在SecurityContextPersistenceFilter後面)。若是任何URL用requires-channel屬性聲明使用特定類型的協議,o.s.s.web.access.channel.ChannelProcessingFilter將會自動添加到過濾器鏈上

ChannelProcessingFilter在請求時的交互過程以下圖所示:

    若是你的應用須要超出內置功能的複雜邏輯,ChannelProcessingFilter的設計能夠進行擴展和加強。注意咱們儘管只在圖中說明了SecureChannelProcessor和RetryWithHttpsEntryPoint的實現,可是有相似的類去校驗和處理聲明爲要求HTTP的URL。

    注意,ChannelEntryPoint使用了HTTP 302的URL重寫,這就不能使用這種技術去重定向POST的URL(儘管典型的POST請求不該該在安全協議和不安全協議間傳遞,由於大多數的應用都會對這種行爲提出警告)。

安全的端口映射

    在一些特定的環境中,可能不會使用標準的HTTP和HTTPS端口,其默認爲80/443或8080/8443。在這種狀況下,你必須配置你的應用包含明確的端口映射,這樣ChannelEntryPoint的實現可以肯定當重定向用戶到安全或不安全的URL時,使用什麼端口。

    這僅須要增長額外的配置元素<port-mappings>,它可以指明除了默認的端口之外,額外的HTTP 的HTTPS端口:

<port-mappings>
  <port-mapping http="9080" https="9443"/>
</port-mappings>

若是你的應用服務器在反向代理後的話,端口映射將會更加的重要。

小結

  1. 介紹了把安全數據存儲在支持JDBC的數據庫中是如何配置的;

  2. 配置JBCP Pets使用數據庫來進行用戶認證以及高安全性的密碼存儲,這裏咱們使用了密碼加密和salting技術;

  3. 管理JDBC持久化到數據中的用戶;

  4. 配置用戶到安全組中。組被授予角色,而不是直接對用戶進行角色的指定。這提升了站點和用戶功能的可管理性;

  5. 介紹了Spring Security使用遺留的(非默認的)數據庫schema

  6. 講解了HTTPS技術的配置及應用,它可以提升數據在訪問應用敏感內容時的安全性。

在接下來的章節中,咱們將會介紹Spring Security一些高級的受權功能,並引入Spring SecurityJSP標籤以實現良好的受權。

相關文章
相關標籤/搜索