spring 第十章 Acegi安全框架

news/2024/7/4 1:41:35 标签: acegi, spring, 框架, bean, authentication, class
class="baidu_pl">
class="article_content clearfix">
class="htmledit_views">

 第10章 Acegi安全class="tags" href="/tags/KuangJia.html" title=框架>框架
安全保护机制三步曲:认证管理器,决策管理器,过滤器链
认证和授权
一基于角色的权限控制 (Role Based Access Control RBAC)
  授权-角色-用户
Java验证和授权服务(Java Authentication and Authorization Service,JAAS)是标准的谁和授权服务
二Acegi安全class="tags" href="/tags/KuangJia.html" title=框架>框架
1.Authentication对象封装了Principal(主体,通常是用户信息)和Credentials(凭证,通常中口令).
  Acegi使用SecurityContext(代替HttpSession,是ThreadLocal..)来存储Authentication.(方法SecurityContextHolder.getContext.getAuthentication() )
2.有了Authentication,再通过下几个组件 ,来确保被访问资源的安全
                            3 安全拦截器(FilterChain,过滤器链)


认证管理器 1         决策管理器   2        运行管理器        
(AuthenticationManager  (AccessDecisionManager,决定是否有权限)
 验证身份)
3详细讲解
 3.1AuthencationManager认证管理器,该组件的任务就是对用户进行认证。认证管理器通过识别
Principal和Credentials来确定用户的身份。
Acegi提供了一个默认的Authentication的实现类ProviderManager.
ProviderManager并不直接去验证用户提供的Principal和Credentials,而是将它们委托给一个或多个AuthenticationProvider来验证,ProviderManager将逐一遍历每个AuthenticationProvider,
只要有一个Authentication Provider成功地认证了用户有,该认证过程就结束。
eg.
   <class="tags" href="/tags/BEAN.html" title=bean>bean id="class="tags" href="/tags/AUTHENTICATION.html" title=authentication>authenticationManager" class="org.class="tags" href="/tags/ACEGI.html" title=acegi>acegisecurity.providers.ProviderManager">
        <property name="providers">
            <list>
                <ref class="tags" href="/tags/BEAN.html" title=bean>bean="daoAuthenticationProvider" />
                <ref class="tags" href="/tags/BEAN.html" title=bean>bean="rememberMeAuthenticationProvider" />
            </list>
        </property>
    </class="tags" href="/tags/BEAN.html" title=bean>bean>
 <!-- 基于DAO验证的AuthenticationProvider -->
    <class="tags" href="/tags/BEAN.html" title=bean>bean id="daoAuthenticationProvider"
        class="org.class="tags" href="/tags/ACEGI.html" title=acegi>acegisecurity.providers.dao.DaoAuthenticationProvider">
        <property name="userDetailsService" ref="userDetailsService" />
    </class="tags" href="/tags/BEAN.html" title=bean>bean>

    <class="tags" href="/tags/BEAN.html" title=bean>bean id="rememberMeAuthenticationProvider"
        class="org.class="tags" href="/tags/ACEGI.html" title=acegi>acegisecurity.providers.rememberme.RememberMeAuthenticationProvider">
        <property name="key" value="remember_Me" />
    </class="tags" href="/tags/BEAN.html" title=bean>bean>

<!-- 使用内存DAO,实际应用时可用JdbcDao代替?? -->
    <class="tags" href="/tags/BEAN.html" title=bean>bean id="userDetailsService"
        class="org.class="tags" href="/tags/ACEGI.html" title=acegi>acegisecurity.userdetails.memory.InMemoryDaoImpl">
        <property name="userMap">
            <value>
                admin=password,enabled,ROLE_ADMIN,ROLE_USER  //格式“用户名=口令,<账户是否有效>,<角色1>,<角色2>”
                test=test,enabled,ROLE_USER
                guest=guest,disabled,ROLE_USER
            </value>
        </property>
    </class="tags" href="/tags/BEAN.html" title=bean>bean>
Acegi已经提供了多个Authentication Provider可供选择:
  AuthByAdapterProvider: 通过Web容器来验证用户身份。
  CasAuthenticationProvider:通过CAS服务来验证用户身份,是基于单点登陆的认证方式。
 DaoAuthenticationProvider:通过数据库存储的用户名口令信息来验证用户身份,这是Web应用程序最常见的认证方式
 JassAuthenticationProvider:通过JAAS服务来验证用户身份。
 PasswordDaoAuthenticationProvider:通过数据库认证,但是具体过程由底层数据源完成
 RememberMeAuthenticationProvider:通过浏览器提供的Cookie来验证用户上次是否已经成功登陆并在有效期内,
若Cookie被接受,则通过认证。
 RemoteAuthenticationProvider:通过远程服务验证用户身份.

3.2AccessDecisionManager(决策管理器)
   <class="tags" href="/tags/BEAN.html" title=bean>bean id="accessDecisionManager"
        class="org.class="tags" href="/tags/ACEGI.html" title=acegi>acegisecurity.vote.AffirmativeBased">   //AffirmativeBased,ConsensusBased,UnamouseBased三种值
        <property name="decisionVoters">                      //每个投票者(RoleVoter)可以以3种方式进行投票:
//ACCESS_GRANTED赞/成票,ACCESS_DENIED拒绝票,ACCESS_ABSTAIN弃权票
            <list>
                <class="tags" href="/tags/BEAN.html" title=bean>bean class="org.class="tags" href="/tags/ACEGI.html" title=acegi>acegisecurity.vote.RoleVoter" />
            </list>
        </property>
        <property name="allowIfAllAbstainDecisions" value="false" />  //allowIfAllAbstainDecisions
    </class="tags" href="/tags/BEAN.html" title=bean>bean>

AffirmativeBased:至少有一个投票者允许访问该资源,这是最常见的方式。
ConsensusBased:所有投票者都允许访问时,才允许访问该资源,这是最严格的方式。
UnamouseBased:如果没有投票者拒绝访问,就允许访问该资源。
这3个accessDecisionManager有一个共同的allowIfAllAbstainDecisions属性,设为true,表示如果所有的投票者都
弃权,也可以允许访问。 为flase,则都弃权,也不可以访问。
 
3.3FilterChain
Acegi已经提供了一系列非常有用的Filter.
1ChannelProcessingFilter:确保当前URL以指定的协议访问,例如,必须对以/secure/开头的URL使用HTTPS访问。
2ConcurrentSessionFilter:阻止同一用户在某一段时间内多次登陆。
3HttpSessionContextIntegrationFilter:由于用户的认证信息存放在Http Session 中,这个过滤器的作用就是从Session
中获得用户的认证信息,然后将其关联到当前请求中,如果没有这个过滤器,后续的请求处理就无法获得已认证的用户的身份信息。
4LogoutFilter:通过过滤特定的URL(例如/j_logout),LogoutFilter可以实现用户注销的功能。
5AuthenticationProcessingFilter:通过过滤特定的URL(例如,/j_security_check)),AuthenticationProcessingFilter可以
 验证用户朐和口令,实现用户登陆的功能。   Acegi提供了多种登录的方式,除了由应用程序自身通过JDBC验证外,
还有CasProcessingFilter,JbossIntegrationFilter等。
6SecurityContextHolderAwareRequestFilter:如果应有用程序需要调用HttpServlet Request的getRemoteUser()获得用户
身份,就可以使用SecurityContextHolder Aware RequestFilter来包装原始的HttpServletRequest,它使用一个代理模式返回Acegi Authentication对象的Principal.
7 RememberMeProcessingFilter:实现雇用户登录信息的功能,使用户在一段时间内都不必输入用户名和口令,Acegi
默认采用Cookie记住用户登录信息。
8 AnonymouseProcessingFilter:如果当前用户没有登录,就将一个匿名用户身份放入SecurityContext中。
9 ExceptionTranslationFilter:捕获任何与Acegi安全相关的异常,然后根据需要将用户导向到登录页面,或者直接发送
一个403禁止访问的错误代码。
10 FilterSecurityInterceptor:最终真正保护Web资源的拦截器。

三实例
eg1.保护web资源,工程名:Spring_Acegi(通过Filter来对web页面进行保护,Filter有对URL过滤的功能,有些用户能访问/user目录,有些访问/admin目录)
知识点:Acegi有多个Filter,但我们却只需在web.xml中配置一个特殊的
Acegi Filter(FilterChainProxy)
 <!-- Acegi过滤器 -->
    <filter>
        <filter-name>class="tags" href="/tags/ACEGI.html" title=acegi>acegiFilterChain</filter-name>
        <filter-class>org.class="tags" href="/tags/ACEGI.html" title=acegi>acegisecurity.util.FilterToBeanProxy</filter-class>
        <init-param>
            <param-name>targetClass</param-name>
            <param-value>org.class="tags" href="/tags/ACEGI.html" title=acegi>acegisecurity.util.FilterChainProxy</param-value>
        </init-param>
    </filter>
其他的Filter通过依赖注入的方式在Acegi的Spring xml中定义。(在security.xml中 过滤器链中链上...
<value>/**=httpSessionContextIntegrationFilter,logoutFilter,class="tags" href="/tags/AUTHENTICATION.html" title=authentication>authenticationProcessingFilter,rememberMeFilter,exceptionFilter,securityInterceptor </value>)


security.xml
<!--========================================================================
         认证管理器
    =========================================================================-->
    <class="tags" href="/tags/BEAN.html" title=bean>bean id="class="tags" href="/tags/AUTHENTICATION.html" title=authentication>authenticationManager" class="org.class="tags" href="/tags/ACEGI.html" title=acegi>acegisecurity.providers.ProviderManager">
        <property name="providers">
            <list>
                <ref class="tags" href="/tags/BEAN.html" title=bean>bean="daoAuthenticationProvider" />
                <ref class="tags" href="/tags/BEAN.html" title=bean>bean="rememberMeAuthenticationProvider" />
            </list>
        </property>
    </class="tags" href="/tags/BEAN.html" title=bean>bean>

    <!-- 基于DAO验证的AuthenticationProvider -->
    <class="tags" href="/tags/BEAN.html" title=bean>bean id="daoAuthenticationProvider"
        class="org.class="tags" href="/tags/ACEGI.html" title=acegi>acegisecurity.providers.dao.DaoAuthenticationProvider">
        <property name="userDetailsService" ref="userDetailsService" />
    </class="tags" href="/tags/BEAN.html" title=bean>bean>

    <class="tags" href="/tags/BEAN.html" title=bean>bean id="rememberMeAuthenticationProvider"
        class="org.class="tags" href="/tags/ACEGI.html" title=acegi>acegisecurity.providers.rememberme.RememberMeAuthenticationProvider">
        <property name="key" value="remember_Me" />
    </class="tags" href="/tags/BEAN.html" title=bean>bean>

    <!-- 使用内存DAO,实际应用时可用JdbcDao代替 -->
    <class="tags" href="/tags/BEAN.html" title=bean>bean id="userDetailsService"
        class="org.class="tags" href="/tags/ACEGI.html" title=acegi>acegisecurity.userdetails.memory.InMemoryDaoImpl">
        <property name="userMap">
            <value>
                admin=password,enabled,ROLE_ADMIN,ROLE_USER
                test=test,enabled,ROLE_USER
                guest=guest,disabled,ROLE_USER
            </value>
        </property>
    </class="tags" href="/tags/BEAN.html" title=bean>bean>

    <!--========================================================================
         决策管理器
    =========================================================================-->
    <class="tags" href="/tags/BEAN.html" title=bean>bean id="accessDecisionManager"
        class="org.class="tags" href="/tags/ACEGI.html" title=acegi>acegisecurity.vote.AffirmativeBased">
        <property name="decisionVoters">
            <list>
                <class="tags" href="/tags/BEAN.html" title=bean>bean class="org.class="tags" href="/tags/ACEGI.html" title=acegi>acegisecurity.vote.RoleVoter" />
            </list>
        </property>
        <property name="allowIfAllAbstainDecisions" value="false" />
    </class="tags" href="/tags/BEAN.html" title=bean>bean>
  <!--========================================================================
         过滤器链
    =========================================================================-->

    <class="tags" href="/tags/BEAN.html" title=bean>bean id="filterChainProxy" class="org.class="tags" href="/tags/ACEGI.html" title=acegi>acegisecurity.util.FilterChainProxy">
        <property name="filterInvocationDefinitionSource">
            <value>
                CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
                PATTERN_TYPE_APACHE_ANT
                /**=httpSessionContextIntegrationFilter,logoutFilter,class="tags" href="/tags/AUTHENTICATION.html" title=authentication>authenticationProcessingFilter,rememberMeFilter,exceptionFilter,securityInterceptor
            </value>     //越详细的过滤器要放前面
        </property>
    </class="tags" href="/tags/BEAN.html" title=bean>bean>
  
 <!-- 基于URL的安全拦截器 -->
    <class="tags" href="/tags/BEAN.html" title=bean>bean id="securityInterceptor"
        class="org.class="tags" href="/tags/ACEGI.html" title=acegi>acegisecurity.intercept.web.FilterSecurityInterceptor">
        <property name="class="tags" href="/tags/AUTHENTICATION.html" title=authentication>authenticationManager" ref="class="tags" href="/tags/AUTHENTICATION.html" title=authentication>authenticationManager" />
        <property name="accessDecisionManager" ref="accessDecisionManager" />
        <property name="objectDefinitionSource">
            <value>
                CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
                PATTERN_TYPE_APACHE_ANT
                /admin/**=ROLE_ADMIN             //对应哪个文件夹 哪种角色才可以访问
                /user/**=ROLE_USER
            </value>
        </property>
    </class="tags" href="/tags/BEAN.html" title=bean>bean>

   <!-- 验证用户身份 ,登陆-->
    <class="tags" href="/tags/BEAN.html" title=bean>bean id="class="tags" href="/tags/AUTHENTICATION.html" title=authentication>authenticationProcessingFilter"
        class="org.class="tags" href="/tags/ACEGI.html" title=acegi>acegisecurity.ui.webapp.AuthenticationProcessingFilter">
        <property name="class="tags" href="/tags/AUTHENTICATION.html" title=authentication>authenticationManager" ref="class="tags" href="/tags/AUTHENTICATION.html" title=authentication>authenticationManager" />
        <property name="class="tags" href="/tags/AUTHENTICATION.html" title=authentication>authenticationFailureUrl" value="/login.jsp?login_error=Login%20failed." />
        <property name="defaultTargetUrl" value="/helloWorld.jsp" />
        <property name="filterProcessesUrl" value="/j_login.do" />
        <property name="rememberMeServices" ref="rememberMeServices" />
    </class="tags" href="/tags/BEAN.html" title=bean>bean>
<!-- 登出-->
    <class="tags" href="/tags/BEAN.html" title=bean>bean id="logoutFilter" class="org.class="tags" href="/tags/ACEGI.html" title=acegi>acegisecurity.ui.logout.LogoutFilter">
        <!-- URL redirected to after logout -->
        <constructor-arg value="/helloWorld.jsp" />
        <constructor-arg>
            <list>
                <ref class="tags" href="/tags/BEAN.html" title=bean>bean="rememberMeServices" />
                <class="tags" href="/tags/BEAN.html" title=bean>bean class="org.class="tags" href="/tags/ACEGI.html" title=acegi>acegisecurity.ui.logout.SecurityContextLogoutHandler" />
            </list>
        </constructor-arg>
        <property name="filterProcessesUrl" value="/j_logout.do" />
    </class="tags" href="/tags/BEAN.html" title=bean>bean>
   <!-- 记住用户登录信息   remeberMeFilter和remeberMeServices配合就实现了自动登陆功能-->
    <class="tags" href="/tags/BEAN.html" title=bean>bean id="rememberMeFilter" class="org.class="tags" href="/tags/ACEGI.html" title=acegi>acegisecurity.ui.rememberme.RememberMeProcessingFilter">
        <property name="class="tags" href="/tags/AUTHENTICATION.html" title=authentication>authenticationManager" ref="class="tags" href="/tags/AUTHENTICATION.html" title=authentication>authenticationManager" />
        <property name="rememberMeServices" ref="rememberMeServices" />
    </class="tags" href="/tags/BEAN.html" title=bean>bean>
 <class="tags" href="/tags/BEAN.html" title=bean>bean id="rememberMeServices" class="org.class="tags" href="/tags/ACEGI.html" title=acegi>acegisecurity.ui.rememberme.TokenBasedRememberMeServices">
        <property name="userDetailsService" ref="userDetailsService" />
        <property name="parameter" value="j_remember_me" />
        <property name="key" value="remember_Me" />
        <property name="tokenValiditySeconds" value="31536000" />
    </class="tags" href="/tags/BEAN.html" title=bean>bean>

  <!-- 处理登录异常或权限异常的Filter -->
    <class="tags" href="/tags/BEAN.html" title=bean>bean id="exceptionFilter" class="org.class="tags" href="/tags/ACEGI.html" title=acegi>acegisecurity.ui.ExceptionTranslationFilter">
        <!-- 出现AuthenticationException时的登录入口 -->
        <property name="class="tags" href="/tags/AUTHENTICATION.html" title=authentication>authenticationEntryPoint">
            <class="tags" href="/tags/BEAN.html" title=bean>bean class="org.class="tags" href="/tags/ACEGI.html" title=acegi>acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint">
                <property name="loginFormUrl" value="/login.jsp" />
                <property name="forceHttps" value="false" />
            </class="tags" href="/tags/BEAN.html" title=bean>bean>
        </property>
        <!-- 出现AccessDeniedException时的Handler -->
        <property name="accessDeniedHandler">
            <class="tags" href="/tags/BEAN.html" title=bean>bean class="org.class="tags" href="/tags/ACEGI.html" title=acegi>acegisecurity.ui.AccessDeniedHandlerImpl" />
            <!-- 可选属性: property name="errorPage" value="/denied.html" -->
        </property>
    </class="tags" href="/tags/BEAN.html" title=bean>bean>

 <!-- 从Session中获得用户信息并放入SecurityContextHolder -->
    <class="tags" href="/tags/BEAN.html" title=bean>bean id="httpSessionContextIntegrationFilter"
        class="org.class="tags" href="/tags/ACEGI.html" title=acegi>acegisecurity.context.HttpSessionContextIntegrationFilter" />
-----------------------------------------完
书中p376的图10-6为该例的结构图。

Spring的配置文件:dispatcher_servlet.xml
Acegi安全class="tags" href="/tags/KuangJia.html" title=框架>框架的配置文件:security.xml

 

实例2,保护Bean组件 未完~````````


http://www.niftyadmin.cn/n/1425687.html

相关文章

Spring核心技术与最佳实践 练习

网上书店来完成整个spring的练习 http://www.livebookstore.net/listBooks.jspx 第一部分第一章 初识Spring1.1 JavaEE平台的诞生和发展1.2 Spring的起源1.3 Spring框架介绍1.3.1 Spring的核心IoC容器1.3.2 Spring对AOP的支持1.3.3 Spring对数据访问的封装1.3.4 Spring的声明式…

*使用软件更新来安装Eclipse的插件

1.使用Bytecode Outline直接查看字节码 安装步骤如下&#xff1a; 帮助/软件更新/查找并安装 名称:Bytecode Outline url http://download.forge.objectweb.org/eclipse-update/ 2.WAR文件的打包生成使用JBossIDE 的 packaging Configurations帮助/软件更新/查找并安装 h…

HSQLDB的使用

HSQLDB的使用(通过纯Java创建数据库&#xff0c;可视化工具创建表;和其他数据库仅Driver,url写法不同而已) 1) hsqldb.jar (库/添加JAR) 2)纯java创建数据库(连接就是创建了)import java.sql.*;public class MemoryDB { public static void main(String[] args) { // TODO 自动…

iOS开发masonry动态布局cell高度

说到iOS自动布局&#xff0c;有很多的解决办法。有的人使用xib/storyboard自动布局&#xff0c;也有人使用frame来适配。对于前者&#xff0c;笔者并不喜欢&#xff0c;也不支持。对于后者&#xff0c;更是麻烦&#xff0c;到处计算高度、宽度等&#xff0c;千万大量代码的冗余…

Struts的validation

Struts的validation对actionForm.java右击 选择源代码/覆盖/实现方法 上选上Validate方法使用ActionErrors 对象&#xff0c;方法add("key",new ActionMessage("显示的信 息"));return actionErrors;5.再次使用cvs

iOS UIWebView 自定义请求头 UserAgent

我的需求是&#xff1a;用户使用我的APP浏览web页面&#xff0c;服务器需要判断该页面是从哪种设备及途径进入的&#xff0c;我的解决思路就是修改系统默认的用户代理UserAgent。 开始是在UIWebView 的 Request 的 Header 中设置 UserAgent&#xff0c;最后没有弄出来。后来在网…

Struts中使用Spring装配各个组件

Struts中使用Spring装配各个组件好处&#xff1a;运行期才对组件进行注入&#xff0c;减少依赖。Struts和Spring结合需要完成以下的2点。1。在Struts的配置文件中添加Spring插件&#xff0c;<plug-in className"org.springframework.web.struts.ContextLoaderPlugin&qu…

OC 与 JS 交互遇到的坑

最近做的项目中有一个需要在web页中判断APP是否登陆&#xff0c;如果没有登陆跳转到APP的登陆界面去登陆。而在这里面技术方面主要就是涉及到web端和服务端的交互&#xff0c;web前端和iOS、Android的交互。 iOS原生应用和web页面的交互大致上有这几种方法iOS7之后的JavaScrip…