Spring-Security 3初體驗

Spring-Security 3初體驗

  使用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>
    <param-name>contextConfigLocation</param-name>
    <param-value>
            /WEB-INF/security-config.xml
    </param-value>
</context-param>

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

  主要設定有二:一個是設定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"?>
<beans:beans xmlns="
http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsd
 http://www.springframework.org/schema/securityhttp://www.springframework.org/schema/security/spring-security-3.0.xsd">
   
<http use-expressions="true" auto-config="true">
        <intercept-url pattern="/secure/protected.jsp" access="hasRole('ROLE_USER')"/>
        <intercept-url pattern="/login.jsp" access="isAnonymous()"/>
        <intercept-url pattern="/**" access="permitAll"/>
        <form-login login-processing-url="/j_spring_security_check"
         login-page="/login.jsp" default-target-url="/index.jsp"
         authentication-failure-url="/login.jsp?error=1"/>
        <logout logout-url="/j_spring_security_logout"/>
    </http>
    <authentication-manager>
        <authentication-provider user-service-ref="securityManager"/>
    </authentication-manager>
    <beans:bean id="securityManager" class="com.blogspot.lawpronotes.security.SecurityManager"/>
</beans:beans>

  <http>標籤目的在於透過AOP方式指定URL Pattern的使用權限,其auto-config="true"的設定,可以在url pattern不用明確指定,比如pattern="/**"即是指其它的URL Pattern皆適用;而use-expression="true"的設定,可以在access屬性使用Spring EL(Spring Expression Language),是故:

  1. hasRole('ROLE_USER'):只允許ROLE_USER存取。而像hasAnyRole('Role1', 'Role2', …)則可設定多角色存取。
  2. isAnonymous():只允許尚未Login的存取。
  3. 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')")
public void create(Contact contact);
// OR
@PreAuthorize("hasPermission(#contact, 'admin')")
public void deletePermission(Contact contact, Sid recipient, Permission permission);
// OR
@PreAuthorize("#contact.name == principal.name)")
public void doSomething(Contact contact);

  上述的security-context.xml尚未講到<form-login>和<logout>兩個標籤,各自對映到/j_spring_security_check和/j_spring_security_logout,這是Spring Security預設的Filter URL,當然可以改寫,但超出自身修維之外了。

  整個流程是:

  1. <http>標籤對url pattern過濾後轉給<authentication-manager>指定的bean處理,該bean即繼承UserDetailsService的class。
  2. 藉由該bean的loadUserByUsername這個method去存取DB或LDAP驗證,驗證成功再return繼承UserDetails的instance。
  3. return後由Spring-Security去驗證密碼和授權,來決定是否允許access。
  4. 在上面步驟2和3之間,繼承UserDetails的instance在被New出時,就要設好其interface的屬性,重要如username、password和Authorizes等,這些來源應該在執行loadUserByUsername結束之前就要完成設置。

你可能感兴趣的:(spring,bean,jsp,Security,Access)