使用Spring Security 3來保護頁面。這篇Blog是寫得非常好的Spring-Security 3的入門飯粒。已於2010/2/19發行了3.0.2版了。
Spring-Security已把認證授權該實作的細節隱藏得相當好,開發者可只須注重業務層次。其官方文件強調Spring-Security是以Layer(層)作為Security控管的單位。業務層次的程式是以繼承UserDetails和UserDetailsService兩大介面為主,範例裡講得蠻清楚的。這裡是對Configruation file加以補述。
第一步是設定web.xml。必要設定如下:
<context-param> <listener> <filter> |
主要設定有二:一個是設定Filter(紅字部份),可以使Spring-Security在Web起作用,作用範圍就是url-pattern所指定的。第二個是畫有底線的security-config.xml,由Spring Context載入,為Spring Security設定所在。
第二步是Spring config的設定(security-config.xml):
<?xml version="1.0" encoding="UTF-8"?> |
<http>標籤目的在於透過AOP方式指定URL Pattern的使用權限,其auto-config="true"的設定,可以在url pattern不用明確指定,比如pattern="/**"即是指其它的URL Pattern皆適用;而use-expression="true"的設定,可以在access屬性使用Spring EL(Spring Expression Language),是故:
- hasRole('ROLE_USER'):只允許ROLE_USER存取。而像hasAnyRole('Role1', 'Role2', …)則可設定多角色存取。
- isAnonymous():只允許尚未Login的存取。
- permitAll:表示url pattern不限制任何角色皆可存取。
而Spring EL尚有以下的common built-in expression:principal、authentication、denyAll、isRememberMe()、isAuthenticated()、isFullyAuthenticated()等,以及Web Security Expression如:hasIpAddress。是故可以如下用and方式P設定:
<intercept-url pattern="/admin*" access="hasRole('admin') and hasIpAddress('192.168.1.0/24')"/> |
除了Common built-in和Web Security的Expression之外,也提供annotation expression,如Method Security Expression,使用它的話事先要在context.xml宣告如下
<global-method-security pre-post-annotations="enabled"/> |
如此一來才能在Bean Class的method做這樣的設定:
@PreAuthorize("hasRole('ROLE_USER')") |
上述的security-context.xml尚未講到<form-login>和<logout>兩個標籤,各自對映到/j_spring_security_check和/j_spring_security_logout,這是Spring Security預設的Filter URL,當然可以改寫,但超出自身修維之外了。
整個流程是:
- <http>標籤對url pattern過濾後轉給<authentication-manager>指定的bean處理,該bean即繼承UserDetailsService的class。
- 藉由該bean的loadUserByUsername這個method去存取DB或LDAP驗證,驗證成功再return繼承UserDetails的instance。
- return後由Spring-Security去驗證密碼和授權,來決定是否允許access。
- 在上面步驟2和3之間,繼承UserDetails的instance在被New出時,就要設好其interface的屬性,重要如username、password和Authorizes等,這些來源應該在執行loadUserByUsername結束之前就要完成設置。