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

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

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

    繼續(xù)關注我的C語言學習博客

    林臨的地盤

    java學習博客
    posts - 44, comments - 28, trackbacks - 0, articles - 0
      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

    用Acegi為你的Spring應用加把鎖

    Posted on 2007-03-06 09:28 lubaolin 閱讀(259) 評論(0)  編輯  收藏

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

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

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

    [web.xml]
    實現(xiàn)認證和授權的最常用的方法是通過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) 首先,你的數(shù)據(jù)庫中必須具有保存用戶名和密碼的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) 添加訪問你的數(shù)據(jù)庫的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中定義哪些頁面需要權限訪問,需要根據(jù)自己的應用需求進行修改,我上面給出
    的定義的意思是這樣的:
    ?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可實現(xiàn)對對象中的方法的權限控制,使用方法可參看Acegi自帶的文檔
    和contact范例。

    [最后要說的]
    本來以為只是說明如何使用Acegi而已,應該非常簡單,但真正寫起來才發(fā)現(xiàn)想要條理清楚的理順所有需要的bean還是很
    困難的,但愿我沒有遺漏太多東西,如果我的文章有什么遺漏或錯誤的話,還請參看Acegi自帶的quick-start范例,但請
    注意,這個范例是不能直接拿來用的。


    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導航:
     
    繼續(xù)關注我的C語言學習博客
    主站蜘蛛池模板: 日本免费福利视频| 最近免费mv在线观看动漫| 亚洲aⅴ无码专区在线观看春色 | 亚洲国产精品综合久久20| 亚洲人成色在线观看| 中文字幕乱理片免费完整的| 97在线线免费观看视频在线观看| 亚洲日本一区二区三区在线不卡| 亚洲不卡av不卡一区二区| 亚洲日本乱码卡2卡3卡新区| 亚洲国产精品VA在线看黑人| 精品日韩99亚洲的在线发布| 精品一区二区三区免费视频| 成年人网站在线免费观看| 亚洲无线电影官网| 亚洲爆乳成av人在线视菜奈实| 91视频免费观看| 国产亚洲综合成人91精品| 豆国产96在线|亚洲| 97性无码区免费| 亚洲精品精华液一区二区 | 在线免费观看国产| 亚洲专区中文字幕| 国产免费久久精品久久久| 99久久婷婷国产综合亚洲| 久久一本岛在免费线观看2020| 免费国产人做人视频在线观看| 亚洲成人福利在线观看| 老司机69精品成免费视频| 亚洲免费日韩无码系列| 亚洲成AV人片在WWW| 最新欧洲大片免费在线| 99久久精品国产亚洲| 七色永久性tv网站免费看| 国产亚洲精品影视在线产品| 黄色毛片视频免费| 亚洲一区影音先锋色资源| 日本一区二区免费看| 亚洲AV成人无码久久精品老人| 99视频在线观看免费| 亚洲人成中文字幕在线观看 |