HTTP基本認證
1. 簡介
在HTTP中,基本認證是一種用來允許Web浏覽器或其他用戶端程式在請求時提供使用者名和密碼形式的身份憑證的一種登入驗證方式。
在發送之前是以使用者名追加一個冒号然後串接上密碼,并将得出的結果字元串再用Base64算法編碼。例如,提供的使用者名是Aladdin、密碼是open sesame,則拼接後的結果就是Aladdin:open sesame,然後再将其用Base64編碼,得到QWxhZGRpbjpvcGVuIHNlc2FtZQ==。最終将Base64編碼的字元串發送出去,由接收者解碼得到一個由冒号分隔的使用者名和密碼的字元串。
雖然對使用者名和密碼的Base64算法編碼結果很難用肉眼識别解碼,但它仍可以極為輕松地被計算機所解碼,就像其容易編碼一樣。編碼這一步驟的目的并不是安全與隐私,而是為将使用者名和密碼中的不相容的字元轉換為均與HTTP協定相容的字元集。
2. Spring Security配置
Spring對其進行内置支援,是以配置超簡單,<security:http-basic /> 覆寫自動配置就搞定了。
1
2
3
4
5
6
<code><</code><code>security:http</code> <code>auto-config</code><code>=</code><code>"true"</code><code>></code>
<code> </code><code><</code><code>security:intercept-url</code> <code>pattern</code><code>=</code><code>"/hello"</code>
<code> </code><code>access</code><code>=</code><code>"ROLE_ADMIN"</code> <code>/></code>
<code> </code><code><</code><code>security:intercept-url</code> <code>pattern</code><code>=</code><code>"/**"</code> <code>access</code><code>=</code><code>"ROLE_USER"</code> <code>/></code>
<code> </code><code><</code><code>security:http-basic</code> <code>/></code>
<code> </code><code></</code><code>security:http</code><code>></code>
3. 小結
HTTP Basic認證需要浏覽器支援(當然絕大部分浏覽器都支援),彈出的認證視窗是浏覽器實作的而非應用提供的。由于密碼幾乎是以明文方式傳送,是以極其不安全,生産環境一般不會使用這種認證。
HTTP摘要認證
HTTP摘要認證可以看做是HTTP基本認證的更新版,解決了HTTP基本認證最大的缺點,即将傳送的密碼加密,而且是使用不可逆的MD5加密算法。
HTTP摘要認證配置稍微複雜點,需要更改entry-point-ref,和增加custom-filter替換原來的HTTP基本認證Filter。
由于使用自定義Filter,是以不能同時使用auto-config。
對DigestAuthenticationFilter bean,我們可以通過passwordAlreadyEncoded屬性指定密碼是否已經加密,Spring Security Web庫中有DigestAuthUtils類可以用來做HTTP 摘要加密,但該類對包外不可見,是以自己可以拷貝實作一個備用。
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<code><?</code><code>xml</code> <code>version</code><code>=</code><code>"1.0"</code> <code>encoding</code><code>=</code><code>"UTF-8"</code><code>?></code>
<code><</code><code>beans</code> <code>xmlns</code><code>=</code><code>"http://www.springframework.org/schema/beans"</code>
<code> </code><code>xmlns:xsi</code><code>=</code><code>"http://www.w3.org/2001/XMLSchema-instance"</code> <code>xmlns:security</code><code>=</code><code>"http://www.springframework.org/schema/security"</code>
<code> </code><code>xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd</code>
<code> </code><code>http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd"></code>
<code> </code>
<code> </code><code><</code><code>bean</code> <code>id</code><code>=</code><code>"digestFilter"</code> <code>class=</code>
<code> </code><code>"org.springframework.security.web.authentication.www.DigestAuthenticationFilter"></code>
<code> </code><code><</code><code>property</code> <code>name</code><code>=</code><code>"userDetailsService"</code> <code>ref</code><code>=</code><code>"userService"</code><code>/></code>
<code> </code><code><</code><code>property</code> <code>name</code><code>=</code><code>"authenticationEntryPoint"</code> <code>ref</code><code>=</code><code>"digestEntryPoint"</code><code>/></code>
<code> </code><code></</code><code>bean</code><code>></code>
<code> </code><code><</code><code>bean</code> <code>id</code><code>=</code><code>"digestEntryPoint"</code> <code>class=</code>
<code> </code><code>"org.springframework.security.web.authentication.www.DigestAuthenticationEntryPoint"></code>
<code> </code><code><</code><code>property</code> <code>name</code><code>=</code><code>"realmName"</code> <code>value</code><code>=</code><code>"com.stevex.demo"</code><code>/></code>
<code> </code><code><</code><code>property</code> <code>name</code><code>=</code><code>"key"</code> <code>value</code><code>=</code><code>"acegi"</code><code>/> </code>
<code> </code><code><</code><code>property</code> <code>name</code><code>=</code><code>"nonceValiditySeconds"</code> <code>value</code><code>=</code><code>"30"</code><code>/></code>
<code> </code><code><</code><code>security:http</code> <code>entry-point-ref</code><code>=</code><code>"digestEntryPoint"</code><code>></code>
<code> </code><code><</code><code>security:intercept-url</code> <code>pattern</code><code>=</code><code>"/admin"</code>
<code> </code><code><</code><code>security:intercept-url</code> <code>pattern</code><code>=</code><code>"/list"</code> <code>access</code><code>=</code><code>"ROLE_USER"</code> <code>/></code>
<code> </code><code><</code><code>security:logout</code> <code>/></code>
<code> </code><code><</code><code>security:custom-filter</code> <code>ref</code><code>=</code><code>"digestFilter"</code> <code>position</code><code>=</code><code>"BASIC_AUTH_FILTER"</code> <code>/></code>
<code> </code><code><</code><code>security:authentication-manager</code><code>></code>
<code> </code><code><</code><code>security:authentication-provider</code><code>></code>
<code> </code><code><</code><code>security:user-service</code> <code>id</code><code>=</code><code>"userService"</code><code>></code>
<code> </code><code><</code><code>security:user</code> <code>authorities</code><code>=</code><code>"ROLE_USER"</code> <code>name</code><code>=</code><code>"stevex"</code>
<code> </code><code>password</code><code>=</code><code>"stevex"</code> <code>/></code>
<code> </code><code><</code><code>security:user</code> <code>authorities</code><code>=</code><code>"ROLE_USER, ROLE_ADMIN"</code>
<code> </code><code>name</code><code>=</code><code>"admin"</code> <code>password</code><code>=</code><code>"admin"</code> <code>/></code>
<code> </code><code></</code><code>security:user-service</code><code>></code>
<code> </code><code></</code><code>security:authentication-provider</code><code>></code>
<code> </code><code></</code><code>security:authentication-manager</code><code>></code>
<code></</code><code>beans</code><code>></code>
HTTP摘要MD5密碼生成實作
<code>public</code> <code>class</code> <code>DigestUtil {</code>
<code> </code><code>public</code> <code>static</code> <code>void</code> <code>main(String[] args) {</code>
<code> </code><code>System.out.println(encodePasswordInA1Format(</code><code>"stevex"</code><code>,</code><code>"com.stevex.demo"</code><code>,</code><code>"stevex"</code><code>));</code>
<code> </code><code>}</code>
<code> </code>
<code> </code><code>static</code> <code>String encodePasswordInA1Format(String username, String realm, String password) {</code>
<code> </code><code>String a1 = username + </code><code>":"</code> <code>+ realm + </code><code>":"</code> <code>+ password;</code>
<code> </code><code>return</code> <code>md5Hex(a1);</code>
<code> </code><code>static</code> <code>String md5Hex(String data) {</code>
<code> </code><code>MessageDigest digest;</code>
<code> </code><code>try</code> <code>{</code>
<code> </code><code>digest = MessageDigest.getInstance(</code><code>"MD5"</code><code>);</code>
<code> </code><code>} </code><code>catch</code> <code>(NoSuchAlgorithmException e) {</code>
<code> </code><code>throw</code> <code>new</code> <code>IllegalStateException(</code><code>"No MD5 algorithm available!"</code><code>);</code>
<code> </code><code>}</code>
<code> </code><code>return</code> <code>new</code> <code>String(Hex.encode(digest.digest(data.getBytes())));</code>
<code>}</code>
摘要通路認證有意成為一個安全性的折衷,它意圖代替非加密的HTTP基本認證,但是它沒有被設計為替換強認證協定,實際使用也不多。
當然HTTP摘要認證也是需要浏覽器支援的,彈出的驗證視窗來自浏覽器而非應用提供,經過測試,個人感覺Firefox支援比Chrome好。
<a href="http://down.51cto.com/data/2364052" target="_blank">附件:http://down.51cto.com/data/2364052</a>
本文轉自sarchitect 51CTO部落格,原文連結:http://blog.51cto.com/stevex/1358043,如需轉載請自行聯系原作者