<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    OMG,到底在尋找什么..................
    (構造一個完美的J2EE系統所需要的完整知識體系)
    posts - 198,  comments - 37,  trackbacks - 0

    Acegi簡介

    ?????? Acegi安全系統,是一個用于Spring Framework的安全框架,能夠和目前流行的Web容器無縫集成。它使用了Spring的方式提供了安全和認證安全服務,包括使用Bean Context,攔截器和面向接口的編程方式。因此,Acegi安全系統能夠輕松地適用于復雜的安全需求。
    ?????? 安全涉及到兩個不同的概念,認證和授權。前者是關于確認用戶是否確實是他們所宣稱的身份。授權則是關于確認用戶是否有允許執行一個特定的操作。
    ???????在Acegi安全系統中,需要被認證的用戶,系統或代理稱為"Principal"。Acegi安全系統和其他的安全系統不同,它并沒有角色和用戶組的概念。

    Acegi系統設計

    ? 關鍵組件

    ????? Acegi安全系統包含以下七個關鍵的功能組件:
    ???????? l?Authentication對象,包含了Principal,Credential和Principal的授權信息。同時還可以包含關于發起認證請求的客戶的其他信息,如IP地址。
    ??????? 2?ContextHolder對象,使用ThreadLocal儲存Authentication對象的地方。
    ??????? 3?AuthenticationManager,用于認證ContextHolder中的Authentication對象。
    ??????? 4?AccessDecissionManager,用于授權一個特定的操作。
    ??????? 5?RunAsManager,當執行特定的操作時,用于選擇性地替換Authentication對象。
    ??????? 6?Secure Object攔截器,用于協調AuthenticationManager,AccessDecissionManager,RunAsManager和特定操作的執行。
    ??????? 7?ObjectDefinitionSource,包含了特定操作的授權定義。

    ????? 這七個關鍵的功能組件的關系如下圖所示(圖中灰色部分是關鍵組件):


    ? 安全管理對象

    ?????? Acegi安全系統目前支持兩類安全管理對象。
    ?????? 第一類的安全管理對象管理AOP Alliance的MethodInvocation,開發人員可以用它來保護Spring容器中的業務對象。為了使Spring管理的Bean可以作為MethodInvocation來使用,Bean可以通過ProxyFactoryBean和BeanNameAutoProxyCreator來管理,就像在Spring的事務管理一樣使用。
    ?????? 第二類是FilterInvocation。它用過濾器(Filter)來創建,并簡單地包裝了HTTP的ServletRequest,ServletResponse和FilterChain。FilterInvocation可以用來保護HTTP資源。通常,開發人員并不需要了解它的工作機制,因為他們只需要將Filter加入web.xml,Acegi安全系統就可以工作了。

    ? 安全配置參數

    ?????? 每個安全管理對象都可以描述數量不限的各種安全認證請求。例如,MethodInvocation對象可以描述帶有任意參數的任意方法的調用,而FilterInvocation可以描述任意的HTTP URL。
    ?????? Acegi安全系統需要記錄應用于每個認證請求的安全配置參數。例如,對于BankManager.getBalance(int accountNumber)方法和BankManager.approveLoan(int applicationNumber)方法,它們需要的認證請求的安全配置很不相同。
    ?????? 為了保存不同的認證請求的安全配置,需要使用配置參數。從實現的視角來看,配置參數使用ConfigAttribute接口來表示。Acegi安全系統提供了ConfigAttribute接口的一個實現,SecurityConfig,它把配置參數保存為一個字符串。
    ???????ConfigAttributeDefinition類是ConfigAttribute對象的一個簡單的容器,它保存了和特定請求相關的ConfigAttribute的集合。
    ?????? 當安全攔截器收到一個安全認證請求時,需要決定應用哪一個配置參數。換句話說,它需要找出應用于這個請求的ConfigAttributeDefinition對象。這個查找的過程是由ObjectDefinitionSource接口來處理的。這個接口的主要方法是public ConfigAttributeDefinition getAttributes(Object object),其中Object參數是一個安全管理對象。因為安全管理對象包含有認證請求的詳細信息,所以ObjectDefinitionSource接口的實現類可以從中獲得所需的詳細信息,以查找相關的ConfigAttributeDefiniton對象。

    ? Acegi如何工作

    ?????? 為了說明Acegi安全系統如何工作,我們設想一個使用Acegi的例子。通常,一個安全系統需要發揮作用,它必須完成以下的工作:
    ?????? l?首先,系統從客戶端請求中獲得Principal和Credential;
    ??????2?然后系統認證Principal和Credential信息;
    ????? 3?如果認證通過,系統取出Principal的授權信息;
    ????? 4?接下來,客戶端發起操作請求;
    ????? 5?系統根據預先配置的參數檢查Principal對于該操作的授權;
    ????? 6?如果授權檢查通過則執行操作,否則拒絕。

    ????? 那么,Acegi安全系統是如何完成這些工作的呢?首先,我們來看看Acegi安全系統的認證和授權的相關類圖:

    ?

    ?????? 圖中綠色部分是安全攔截器的抽象基類,它包含有兩個管理類,AuthenticationManager和AccessDecisionManager,如圖中灰色部分。AuthenticationManager用于認證ContextHolder中的Authentication對象(包含了Principal,Credential和Principal的授權信息);AccessDecissionManager則用于授權一個特定的操作。
    ????? 下面來看一個MethodSecurityInterceptor的例子:
    ????? <bean id="bankManagerSecurity"
    ???????????????????? class="net.sf.acegisecurity.intercept.method.MethodSecurityInterceptor">
    ?????????????<property name="validateConfigAttributes">
    ??????????????????? <value>true</value>
    ?????????? ?</property>
    ?????????? ?<property name="authenticationManager">
    ????????????????? ?<ref bean="authenticationManager"/>
    ??????????? </property>
    ??????????? <property name="accessDecisionManager">
    ???????????????? ?<ref bean="accessDecisionManager"/>
    ?????????? ?</property>
    ?????????? ?<property name="objectDefinitionSource">
    ???????????????? ?<value>
    ?????????????????????net.sf.acegisecurity.context.BankManager.delete*=
    ?????????????????????????????ROLE_SUPERVISOR,RUN_AS_SERVER
    ?????????????????????net.sf.acegisecurity.context.BankManager.getBalance=
    ???????????????????????????? ROLE_TELLER,ROLE_SUPERVISOR,BANKSECURITY_CUSTOMER,RUN_
    ????????????????? </value>
    ??????????? </property>
    ????? </bean>

    ??????上面的配置文件中,MethodSecurityInterceptor是AbstractSecurityInterceptor的一個實現類。它包含了兩個管理器,authenticationManager和accessDecisionManager。這兩者的配置如下:

    ????? <bean id="authenticationDao" class="net.sf.acegisecurity.providers.dao.jdbc.JdbcDaoImpl">
    ?????????????? <property name="dataSource"><ref bean="dataSource"/></property>
    ????? </bean>
    ????? <bean id="daoAuthenticationProvider"
    ???????????????????? class="net.sf.acegisecurity.providers.dao.DaoAuthenticationProvider">
    ?????????????? <property name="authenticationDao"><ref bean="authenticationDao"/></property>
    ??????</bean>
    ????? <bean id="authenticationManager" class="net.sf.acegisecurity.providers.ProviderManager">
    ?????????????? <property name="providers">
    ????????????????????? <list><ref bean="daoAuthenticationProvider"/></list>
    ????????????? ?</property>
    ????? </bean>

    ????? <bean id="roleVoter" class="net.sf.acegisecurity.vote.RoleVoter"/>
    ????? <bean id="accessDecisionManager" class="net.sf.acegisecurity.vote.AffirmativeBased">
    ?????????????? <property name="allowIfAllAbstainDecisions"><value>false</value></property>
    ?????????????? <property name="decisionVoters">
    ??????????? ???????? ?<list><ref bean="roleVoter"/></list>
    ????????????? ?</property>
    ????? </bean>

    ?????? 準備工作做好了,現在我們來看看Acegi安全系統是如何實現認證和授權機制的。以使用HTTP BASIC認證的應用為例子,它包括下面的步驟:
    ?????? 1.?用戶登錄系統,Acegi從acegisecurity.ui子系統的安全攔截器(如BasicProcessingFilter)中得到用戶的登錄信息(包括Principal和Credential)并放入Authentication對象,并保存在ContextHolder對象中;
    ?????? 2.?安全攔截器將Authentication對象交給AuthenticationManager進行身份認證,如果認證通過,返回帶有Principal授權信息的Authentication對象。此時ContextHolder對象的Authentication對象已擁有Principal的詳細信息;
    ?????? 3.?用戶登錄成功后,繼續進行業務操作;
    ?????? 4.?安全攔截器(bankManagerSecurity)收到客戶端操作請求后,將操作請求的數據包裝成安全管理對象(FilterInvocation或MethodInvocation對象);
    ?????? 5.?然后,從配置文件(ObjectDefinitionSource)中讀出相關的安全配置參數ConfigAttributeDefinition;
    ?????? 6.?接著,安全攔截器取出ContextHolder中的Authentication對象,把它傳遞給AuthenticationManager進行身份認證,并用返回值更新ContextHolder的Authentication對象;
    ?????? 7.?將Authentication對象,ConfigAttributeDefinition對象和安全管理對象(secure Object)交給AccessDecisionManager,檢查Principal的操作授權;
    ???????8.?如果授權檢查通過則執行客戶端請求的操作,否則拒絕;

    ? AccessDecisionVoter

    ?????? 注意上節的accessDecisionManager是一個AffirmativeBased類,它對于用戶授權的投票策略是,只要通過其中的一個授權投票檢查,即可通過;它的allowIfAllAbstainDecisions屬性值是false,意思是如果所有的授權投票是都是棄權,則通不過授權檢查。
    ?????? Acegi安全系統包括了幾個基于投票策略的AccessDecisionManager,上節的RoleVoter就是其中的一個投票策略實現,它是AccessDecisionVoter的一個子類。AccessDecisionVoter的具體實現類通過投票來進行授權決策,AccessDecisionManager則根據投票結果來決定是通過授權檢查,還是拋出AccessDeniedException例外。
    ?????? AccessDecisionVoter接口共有三個方法:
    public int vote(Authentication authentication, Object object, ConfigAttributeDefinition config);
    public boolean supports(ConfigAttribute attribute);
    public boolean supports(Class clazz);
    ?????? 其中的vote方法返回int返回值,它們是AccessDecisionVoter的三個靜態成員屬性:ACCESS_ABSTAIN,,ACCESS_DENIED和ACCESS_GRANTED,它們分別是棄權,否決和贊成。
    ?????? Acegi安全系統中,使用投票策略的AccessDecisionManager共有三個具體實現類:AffirmativeBased、ConsensusBased和UnanimousBased。它們的投票策略是,AffirmativeBased類只需有一個投票贊成即可通過;ConsensusBased類需要大多數投票贊成即可通過;而UnanimousBased類需要所有的投票贊成才能通過。
    ?????? RoleVoter類是一個Acegi安全系統AccessDecisionVoter接口的實現。如果ConfigAttribute以ROLE_開頭,RoleVoter則進行投票。如果GrantedAuthority的getAutority方法的String返回值匹配一個或多個以ROLE_開頭的ConfigAttribute,則投票通過,否則不通過。如果沒有以ROLE_開頭的ConfigAttribute,RoleVoter則棄權。

    安全攔截器

    ? 攔截器如何工作
    ? MethodInvocation攔截器
    ? FilterInvocation攔截器

    認證

    ? 認證請求
    ? 認證管理器
    ? Authentication Provider

    授權

    ? Access Decision Manager
    ? Voting Decision Manager
    ? 授權管理推薦

    ContextHolder的用戶接口

    ? 用戶接口目標
    ? HTTP會話認證
    ? HTTP Basic認證

    [簡介]

    對于一個典型的Web應用,完善的認證和授權機制是必不可少的,在SpringFramework中,Juergen Hoeller提供的范例JPetStore給了一些這方面的介紹,但還遠遠不夠,Acegi是一個專門為SpringFramework提供安全機制的 項目,全稱為Acegi Security System for Spring,當前版本為0.5.1,就其目前提供的功能,應該可以滿足絕大多數應用的需求。

    本文的主要目的是希望能夠說明如何在基于Spring構架的Web應用中使用Acegi,而不是詳細介紹其中的每個接口、每個類。注意,即使對已經存在的Spring應用,通過下面介紹的步驟,也可以馬上享受到Acegi提供的認證和授權。

    [基礎工作]
    在你的Web應用的lib中添加Acegi下載包中的acegi-security.jar

    [web.xml]
    實現認證和授權的最常用的方法是通過filter,Acegi亦是如此,通常Acegi需要在web.xml添加以下5個filter:

    <filter>
    ??<filter-name>Acegi Channel Processing Filter</filter-name>
    ??<filter-class>net.sf.acegisecurity.util.FilterToBeanProxy</filter-class>
    ??<init-param>
    ????<param-name>targetClass</param-name>
    ????<param-value>net.sf.acegisecurity.securechannel.ChannelProcessingFilter</param-value>
    ??</init-param>
    </filter>
    <filter>
    ??<filter-name>Acegi Authentication Processing Filter</filter-name>
    ??<filter-class>net.sf.acegisecurity.util.FilterToBeanProxy</filter-class>
    ??<init-param>
    ????<param-name>targetClass</param-name>
    ????<param-value>net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilter</param-value>
    ??</init-param>
    </filter>
    <filter>
    ??<filter-name>Acegi HTTP BASIC Authorization Filter</filter-name>
    ??<filter-class>net.sf.acegisecurity.util.FilterToBeanProxy</filter-class>
    ??<init-param>
    ????<param-name>targetClass</param-name>
    ????<param-value>net.sf.acegisecurity.ui.basicauth.BasicProcessingFilter</param-value>
    ??</init-param>
    </filter>
    <filter>
    ??<filter-name>Acegi Security System for Spring Auto Integration Filter</filter-name>
    ??<filter-class>net.sf.acegisecurity.ui.AutoIntegrationFilter</filter-class>
    </filter>
    <filter>
    ??<filter-name>Acegi HTTP Request Security Filter</filter-name>
    ??<filter-class>net.sf.acegisecurity.util.FilterToBeanProxy</filter-class>
    ??<init-param>
    ????<param-name>targetClass</param-name>
    ????<param-value>net.sf.acegisecurity.intercept.web.SecurityEnforcementFilter</param-value>
    ??</init-param>
    </filter>



    最先引起迷惑的是net.sf.acegisecurity.util.FilterToBeanProxy,Acegi自己的文檔上解釋是: “What??FilterToBeanProxy does is delegate the Filter's methods through to a bean which is obtained from the
    Spring application context. This enables the bean to benefit from the Spring application context lifecycle support and configuration flexibility.”,如希望深究的話,去看看源代碼應該不難理解。

    再下來就是添加filter-mapping了:

    <filter-mapping>
    ??<filter-name>Acegi Channel Processing Filter</filter-name>
    ??<url-pattern>/*</url-pattern>
    </filter-mapping>
    <filter-mapping>
    ??<filter-name>Acegi Authentication Processing Filter</filter-name>
    ??<url-pattern>/*</url-pattern>
    </filter-mapping>
    <filter-mapping>
    ??<filter-name>Acegi HTTP BASIC Authorization Filter</filter-name>
    ??<url-pattern>/*</url-pattern>
    </filter-mapping>
    <filter-mapping>
    ??<filter-name>Acegi Security System for Spring Auto Integration Filter</filter-name>
    ??<url-pattern>/*</url-pattern>
    </filter-mapping>
    <filter-mapping>
    ??<filter-name>Acegi HTTP Request Security Filter</filter-name>
    ??<url-pattern>/*</url-pattern>
    </filter-mapping>



    這里,需要注意以下兩點:
    1) 這幾個filter的順序是不能更改的,順序不對將無法正常工作;
    2) 如果你的應用不需要安全傳輸,如https,則將"Acegi Channel Processing Filter"相關內容注釋掉即可;
    3) 如果你的應用不需要Spring提供的遠程訪問機制,如Hessian and Burlap,將"Acegi HTTP BASIC Authorization
    Filter"相關內容注釋掉即可。

    [applicationContext.xml]
    接下來就是要添加applicationContext.xml中的內容了,從剛才FilterToBeanFactory的解釋可以看出,真正的filter都
    在Spring的applicationContext中管理:

    1) 首先,你的數據庫中必須具有保存用戶名和密碼的table,Acegi要求table的schema必須如下:

    CREATE TABLE users (
    ????username VARCHAR(50) NOT NULL PRIMARY KEY,
    ????password VARCHAR(50) NOT NULL,
    ????enabled BIT NOT NULL
    );
    CREATE TABLE authorities (
    ????username VARCHAR(50) NOT NULL,
    ????authority VARCHAR(50) NOT NULL
    );
    CREATE UNIQUE INDEX ix_auth_username ON authorities ( username, authority );
    ALTER TABLE authorities ADD CONSTRAINT fk_authorities_users foreign key (username) REFERENCES users
    (username);



    2) 添加訪問你的數據庫的datasource和Acegi的jdbcDao,如下:

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    ??<property name="driverClassName"><value>${jdbc.driverClassName}</value></property>
    ??<property name="url"><value>${jdbc.url}</value></property>
    ??<property name="username"><value>${jdbc.username}</value></property>
    ??<property name="password"><value>${jdbc.password}</value></property>
    </bean>
    <bean id="jdbcDaoImpl" class="net.sf.acegisecurity.providers.dao.jdbc.JdbcDaoImpl">
    ??<property name="dataSource"><ref bean="dataSource"/></property>
    </bean>



    3) 添加DaoAuthenticationProvider:

    <bean id="daoAuthenticationProvider" class="net.sf.acegisecurity.providers.dao.DaoAuthenticationProvider">
    ??<property name="authenticationDao"><ref bean="authenticationDao"/></property>
    ??<property name="userCache"><ref bean="userCache"/></property>
    </bean>

    <bean id="userCache" class="net.sf.acegisecurity.providers.dao.cache.EhCacheBasedUserCache">
    ??<property name="minutesToIdle"><value>5</value></property>
    </bean>



    如果你需要對密碼加密,則在daoAuthenticationProvider中加入:<property name="passwordEncoder"><ref
    bean="passwordEncoder"/></property>,Acegi提供了幾種加密方法,詳細情況可看包
    net.sf.acegisecurity.providers.encoding

    4) 添加authenticationManager:

    <bean id="authenticationManager" class="net.sf.acegisecurity.providers.ProviderManager">
    ??<property name="providers">
    ????<list>
    ??????<ref bean="daoAuthenticationProvider"/>
    ????</list>
    ?? </property>
    </bean>



    5) 添加accessDecisionManager:

    <bean id="accessDecisionManager" class="net.sf.acegisecurity.vote.AffirmativeBased">
    ??<property name="allowIfAllAbstainDecisions">
    ????<value>false</value>
    ??</property>
    ??<property name="decisionVoters">
    ????<list><ref bean="roleVoter"/></list>
    ??</property>
    </bean>
    <bean id="roleVoter" class="net.sf.acegisecurity.vote.RoleVoter"/>



    6) 添加authenticationProcessingFilterEntryPoint:

    <bean id="authenticationProcessingFilterEntryPoint" 
    class="net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint">
    ??<property name="loginFormUrl"><value>/acegilogin.jsp</value></property>
    ??<property name="forceHttps"><value>false</value></property>
    </bean>



    其中acegilogin.jsp是登陸頁面,一個最簡單的登錄頁面如下:

    <%@ taglib prefix='c' uri='http://java.sun.com/jstl/core' %>
    <%@ page import="net.sf.acegisecurity.ui.AbstractProcessingFilter" %>
    <%@ page import="net.sf.acegisecurity.AuthenticationException" %>
    <html>
    ??<head>
    ????<title>Login</title>
    ??</head>

    ??<body>
    ????<h1>Login</h1>
    ????<form action="<c:url value='j_acegi_security_check'/>" method="POST">
    ??????<table>
    ????????<tr><td>User:</td><td><input type='text' name='j_username'></td></tr>
    ????????<tr><td>Password:</td><td><input type='password' name='j_password'></td></tr>
    ????????<tr><td colspan='2'><input name="submit" type="submit"></td></tr>
    ????????<tr><td colspan='2'><input name="reset" type="reset"></td></tr>
    ??????</table>
    ????</form>
    ??</body>
    </html>



    7) 添加filterInvocationInterceptor:

    <bean id="filterInvocationInterceptor" 
    class="net.sf.acegisecurity.intercept.web.FilterSecurityInterceptor">
    ??<property name="authenticationManager">
    ????<ref bean="authenticationManager"/>
    ??</property>
    ??<property name="accessDecisionManager">
    ????<ref bean="accessDecisionManager"/>
    ??</property>
    ??<property name="objectDefinitionSource">
    ????<value>
    ??????CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
    ??????\A/sec/administrator.*\Z=ROLE_SUPERVISOR
    ??????\A/sec/user.*\Z=ROLE_TELLER
    ????</value>
    ??</property>
    </bean>



    這里請注意,要objectDefinitionSource中定義哪些頁面需要權限訪問,需要根據自己的應用需求進行修改,我上面給出
    的定義的意思是這樣的:
    a. CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON意思是在比較請求路徑時全部轉換為小寫
    b. \A/sec/administrator.*\Z=ROLE_SUPERVISOR意思是只有權限為ROLE_SUPERVISOR才能訪問/sec/administrator*的頁面
    c. \A/sec/user.*\Z=ROLE_TELLER意思是只有權限為ROLE_TELLER的用戶才能訪問/sec/user*的頁面

    8) 添加securityEnforcementFilter:

    <bean id="securityEnforcementFilter" class="net.sf.acegisecurity.intercept.web.SecurityEnforcementFilter">
    ??<property name="filterSecurityInterceptor">
    ????<ref bean="filterInvocationInterceptor"/>
    ??</property>
    ??<property name="authenticationEntryPoint">
    ????<ref bean="authenticationProcessingFilterEntryPoint"/>
    ??</property>
    </bean>



    9) 添加authenticationProcessingFilter:

    <bean id="authenticationProcessingFilter" 
    class="net.sf.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
    ??<property name="authenticationManager">
    ????<ref bean="authenticationManager"/>
    ??</property>
    ??<property name="authenticationFailureUrl">
    ????<value>/loginerror.jsp</value>
    ??</property>
    ??<property name="defaultTargetUrl">
    ????<value>/</value>
    ??</property>
    ??<property name="filterProcessesUrl">
    ????<value>/j_acegi_security_check</value>
    ??</property>
    </bean>


    其中authenticationFailureUrl是認證失敗的頁面。

    10) 如果需要一些頁面通過安全通道的話,添加下面的配置:

    <bean id="channelProcessingFilter" class="net.sf.acegisecurity.securechannel.ChannelProcessingFilter">
    ??<property name="channelDecisionManager">
    ????<ref bean="channelDecisionManager"/>
    ??</property>
    ??<property name="filterInvocationDefinitionSource">
    ????<value>
    ??????CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
    ??????\A/sec/administrator.*\Z=REQUIRES_SECURE_CHANNEL
    ??????\A/acegilogin.jsp.*\Z=REQUIRES_SECURE_CHANNEL
    ??????\A/j_acegi_security_check.*\Z=REQUIRES_SECURE_CHANNEL
    ??????\A.*\Z=REQUIRES_INSECURE_CHANNEL
    ????</value>
    ??</property>
    </bean>

    <bean id="channelDecisionManager" class="net.sf.acegisecurity.securechannel.ChannelDecisionManagerImpl">
    ??<property name="channelProcessors">
    ????<list>
    ??????<ref bean="secureChannelProcessor"/>
    ??????<ref bean="insecureChannelProcessor"/>
    ????</list>
    ??</property>
    </bean>
    <bean id="secureChannelProcessor" class="net.sf.acegisecurity.securechannel.SecureChannelProcessor"/>
    <bean id="insecureChannelProcessor" class="net.sf.acegisecurity.securechannel.InsecureChannelProcessor"/>



    [缺少了什么?]
    Acegi目前提供了兩種"secure object",分別對頁面和方法進行安全認證管理,我這里介紹的只是利用
    FilterSecurityInterceptor對訪問頁面的權限控制,除此之外,Acegi還提供了另外一個Interceptor――
    MethodSecurityInterceptor,它結合runAsManager可實現對對象中的方法的權限控制,使用方法可參看Acegi自帶的文檔
    和contact范例。

    [最后要說的]
    本來以為只是說明如何使用Acegi而已,應該非常簡單,但真正寫起來才發現想要條理清楚的理順所有需要的bean還是很
    困難的,但愿我沒有遺漏太多東西,如果我的文章有什么遺漏或錯誤的話,還請參看Acegi自帶的quick-start范例,但請
    注意,這個范例是不能直接拿來用的。
    分析和學習Spring中的jpetstore用戶管理
    ??存在用戶的系統,必然需要用戶的登錄和認證,今天就通過分析Spring中自帶的jpetstore的例子來學習一下如何實現在Spring構架的系統中用戶登錄。
    1、首先從注冊用戶開始,先看看jpetstore-servlet.xml中關于注冊用戶的bean定義,從定義命名中就可以看出下面這段就是注冊用戶的:
    ??

    <bean name="/shop/newAccount.do" class="org.springframework.samples.jpetstore.web.spring.AccountFormController">
    ????<property name="petStore"><ref bean="petStore"/></property>
    ????<property name="validator"><ref bean="accountValidator"/></property>
    ????<property name="successView"><value>index</value></property>
    ??</bean>


    1). formView呢?從AccountFormController的構造函數中得到,原來為EditAccountForm;??
    2). EditoAccountForm.jsp中顯得非常亂,其實沒有多少難理解的地方,最主要的是這個form既是添加新用戶的,又是編輯用戶信息的,所以顯得有點亂糟糟的。
    2、添加好了新用戶,接下來看看如何登錄,在jpetstore-servlet中發現這兩個相關bean定義,如下:
    ??

    <bean name="/shop/signon.do" class="org.springframework.samples.jpetstore.web.spring.SignonController">
    ????<property name="petStore"><ref bean="petStore"/></property>
    ??</bean>
    ??<bean name="/shop/signonForm.do" class="org.springframework.web.servlet.mvc.ParameterizableViewController">
    ????<property name="viewName"><value>SignonForm</value></property>
    ??</bean>


    1). 第二個bean是在運行時用戶輸入用戶名和密碼的form,叫做SignonForm,對于這個 ParameterizableViewController,用文檔里的話說這是最簡單的Controller,其作用就是在運行中指向 Controller而不是直接指向jsp文件,僅此而已。
    2). SignonForm.jsp,里面就是一個簡單的form,其action就是第一個bean,即/shop/signon.do,最需要注意的是 signonForwardAction,其主要作用是forward到需要輸入用戶名和密碼的那個頁面上去,這個變量哪里來的呢?看看下面:
    ??

    <bean id="secureHandlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    ????<property name="interceptors">
    ??????<list>
    ????????<ref bean="signonInterceptor"/>
    ??????</list>
    ????</property>
    ????<property name="urlMap">
    ??????<map>
    ????????<entry key="/shop/editAccount.do"><ref local="secure_editAccount"/></entry>
    ????????<entry key="/shop/listOrders.do"><ref local="secure_listOrders"/></entry>
    ????????<entry key="/shop/newOrder.do"><ref local="secure_newOrder"/></entry>
    ????????<entry key="/shop/viewOrder.do"><ref local="secure_viewOrder"/></entry>
    ??????</map>
    ????</property>
    ??</bean>


    ??原來,上面的signonInterceptor實現了preHandle,因此在請求上面的map頁面時,首先要經過這個Interceptor,看看 SignonInterceptor的源碼,原來在其中為signon.jsp賦予一個signonForwardAction對象,呵呵,總算明白了。
    3). 接下來去學習一下SignonController,其主體部分中可以看出,首先取出用戶輸入的username和password,然后到數據庫中驗證 有沒有這個用戶,如果沒有這個用戶,返回各錯誤頁面;如果成功,首先生成一個UserSession對象,在request的session加入這個 userSession,注意這部分代碼中給出了PagedListHolder分頁的簡單使用方法,關于分頁顯示,以后再學習吧。
    3、登錄成功后,就可以根據不同的用戶設施不同的行為了,取得用戶信息,無非就是從session取出userSession即可

    posted on 2006-10-26 12:58 OMG 閱讀(522) 評論(0)  編輯  收藏 所屬分類: Auth/acegi

    <2006年10月>
    24252627282930
    1234567
    891011121314
    15161718192021
    22232425262728
    2930311234

    常用鏈接

    留言簿(1)

    隨筆分類

    隨筆檔案

    IT風云人物

    文檔

    朋友

    相冊

    經典網站

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 免费人成视频在线| 好男人视频在线观看免费看片 | 亚洲精品电影天堂网| 国产成人AV免费观看| 亚洲av之男人的天堂网站| 你懂的在线免费观看| 久久99国产亚洲高清观看首页| 一级毛片免费毛片毛片| 亚洲中文字幕无码一区二区三区| h视频免费高清在线观看| 亚洲伊人久久综合中文成人网 | a级成人毛片免费图片| 亚洲国产成人高清在线观看| 免费黄网站在线看| 亚洲午夜精品在线| 大学生高清一级毛片免费| 国产成人高清亚洲一区久久| 国产黄色一级毛片亚洲黄片大全| 日本高清不卡aⅴ免费网站| 亚洲国产精品第一区二区| 久久精品免费一区二区喷潮| 亚洲av无码专区在线电影| 亚洲va中文字幕无码| 国产精品99久久免费观看| 国产精品亚洲午夜一区二区三区| 日本a级片免费看| 国产免费高清69式视频在线观看| 亚洲黄色免费在线观看| 日韩中文字幕在线免费观看| 国产精品免费αv视频| 亚洲欧洲精品国产区| 免费在线观看污网站| 国内永久免费crm系统z在线| 久久乐国产综合亚洲精品| 亚洲日本中文字幕一区二区三区| 亚洲视频免费在线观看| 色偷偷亚洲第一综合| 久久精品亚洲综合专区| 永久免费观看的毛片的网站| 大地影院MV在线观看视频免费| 亚洲婷婷第一狠人综合精品|