Acegi是基于Spring的一个开源的安全认证框架,现在的最新版本是1.04。Acegi的特点就是有很多的过滤器:不过我们也用不到这么多的过滤器,只是可以把它们看作为一个个的模块,在用的时候加上自己用的着的即可,由于认证的流程的方面比较复杂导致它的配置很复杂,如果能摸清它的工作原理还是不太难.下面用比较顺着人思维的流程过一遍
这里只列出常用的过滤器和拦载器
1. 过滤器:HttpSessionContextIntegrationFilter,
authenticationProcessingFilter,BasicProcessingFilter,RememberMeProcessingFilter,anonymousProcessingFilter,exceptionTranslationFilter
2. 拦截器:
filterSecurityInterceptor(其实它是过滤器,不过把它放在这里更能说明它的功能),methodSecurityInterceptor
看着上面的用红色标出的过滤器是用来认证(表单和HTTP基本认证,当然还有别的不过这两个比较长用)它们是资源访问的入口.其它的过滤器是用来辅助的:HttpSessionContextIntegrationFilter是用来把认证信息记录到Session中的RememberMeProcessingFilter是以cookie的形式来保存认证信息的. anonymousProcessingFilter是在匿名的时候(这时候是没有认证信息的)给这个用户分配一个匿名的认证信息,exceptionTranslationFilter总结一下异常并处理.在实际中选择适合程序的即可.
上面只是资源访问的入口,真正保护资源的是这两个拦截器:filterSecurityInterceptor,拦截URL的类(它是个过滤器)
metohdSecurityInterceptor,拦截类中方法的调用,它们为什么要拦截呢?就是想在访问或调用这些方法之前来判断一下用户是否有访问或调用的权限,有就通过,没有就踢出.
除此之外,Acegi专门做了两个管理器(实际上就是两个类,为什么会用做这两个管理器,因为认证和授权都有一些的操作,这就需要专门做两个管理器了):authenticationManager(class= org.acegisecurity.providers.ProviderManager),授权管理器accessDecisionManager(class=org.acegisecurity.vote.AffirmativeBased)
说白了一个用于认证用户,一个是用于权限的授于的
先来说认证用户,认证管理器有什么东西呢?只内置了一些提供者:这些提供者呢又是什么呢,他们是提供用户的验证身份信息的,比如从数据库或配置文件里读出用户名和密码,在用户的cookie里读出身份信息(rememberMeProcessingFilter用到的[前面讲了的,有印象吧]),或在Session里读出身份验证信息(HttpSessionContextIntegrationFilter起作用的),这里我们只说一下从数据库或配置文件里读出用户名密码来装配验证信息的,其它的配置类似可以找一下对应api在Spring里配置即可,daoAuthenticationProvider是数据库的提供者class=org.acegisecurity.providers.dao.DaoAuthenticationProvider,而它提供的服务呢又有几种,数据库和配置文件(这是Acegi的两个默认的实现)当然也可以自己实现(实现userDetailsService接口就行)
代码
- <beanid="authenticationManager"class="org.acegisecurity.providers.ProviderManager">
-
<propertyname="providers">
-
<list>
-
<reflocal="daoAuthenticationProvider"/>
-
</list>
-
</property>
-
</bean>
-
<beanid="daoAuthenticationProvider"class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
-
-
<propertyname="userDetailsService"><reflocal="jdbcDaoImpl"/></property>
-
</bean>
render_code();
如果用户名和密码在配置文件里可以用InMemoryDaoImpl,class=org.acegisecurity.userdetails.memory.InMemoryDaoImpl,在这个类的userMap里配置即可:javafish=java,ROLE_USER,配置了一个用户名为javafish,密码为java,用户组为ROLE_USER的用户,不过最常用的还是数据库的JDBC实现(两个二选一)org.acegisecurity.userdetails.jdbc.JdbcDaoImpl里面需要usersByUsernameQuery和authoritiesByUsernameQuery还有数据源dataSource(有人问为什么呢,userByUsernameQuery是用来通过用户名来查密码的,authoritiesByUsernameQuery是用来通过用户名来查权限的,查询数据库肯定的用数据源吧这个里是用的SpringFrameWork的DataSource)它们查询的sql语句是有讲究的,就是查密码的时候查三个第一个是username,第二个是password,第三个是是否可用,查权限的时候查两个:username和authorities(具体看例子)
代码
- <beanid="InMemoryDaoImpl"class="org.acegisecurity.userdetails.memory.InMemoryDaoImpl">
-
<propertyname="userMap">
-
<value>
-
javajavafish=java,ROLE_USER
-
</value>
-
</property>
-
</bean>
-
<beanid="jdbcDaoImpl"class="org.acegisecurity.userdetails.jdbc.JdbcDaoImpl">
-
<propertyname="usersByUsernameQuery">
-
<value>selectusername,password,enabledfromuserswhereusername=?</value>
-
</property>
-
<propertyname="authoritiesByUsernameQuery">
-
<value>selectusername,authorityfromauthoritieswhereusername=?</value>
-
</property>
-
<propertyname="dataSource">
-
<reflocal="dataSource"/>
-
</property>
-
</bean>
-
-
<beanid="dataSource"class="org.springframework.jdbc.datasource.DriverManagerDataSource">
-
<propertyname="driverClassName">
-
<value>com.mysql.jdbc.Driver</value>
-
</property>
-
<propertyname="url">
-
<value>jdbc:mysql://localhost:3306/test</value>
-
</property>
-
<propertyname="username">
-
<value>root</value>
-
</property>
-
<propertyname="password">
-
<value>javafish</value>
-
</property>
-
</bean>
render_code();
下面说一下授权,授权管理器又有什么东西呢?accessDecisionManager,Acegi把授权方面弄的比较的形象化,把某个URL或方法是否可以被访问按投票的形式来决定,
Acegi提出来了几种方案:
1. 如果有一个赞成就同意(具体的说就是只要你在那个URL对应的几个用户组中的一个就让你访问)
2. 如果都赞成就同意(具本的说就是那个URL对应的几个用户组里都有你,你才能访问)
3. 如果都不反对就同意(这个在下面讲投票者的时候再说)
代码
- <beanid="accessDecisionManager"class="org.acegisecurity.vote.AffirmativeBased">
-
<propertyname="allowIfAllAbstainDecisions">
-
<value>false</value>
-
</property>
-
<propertyname="decisionVoters">
-
<refbean="roleVoter"/>
-
</property>
-
</bean>
render_code();
而投票者呢:Acegi自己实现了一个投票者的类RoleVoter:
现在我用第一种方案,RoleVoter只是在URL对应的用户组里有ROLE_为前缀的才进行投票,否则的话弃权.(我们也可以在配置RoleVoter的时候把ROLE_配置成为别的前缀如JAVA_),分别对URL对应的每个用户组投票,如果用户在这个用户组里就投赞成,不在投反对(在用户组的前缀是ROLE_的前提下)这样就不难体会第三种方案的用途了吧
代码
- <beanid="roleVoter"class="org.acegisecurity.vote.RoleVoter">
-
<propertyname="rolePrefix">
-
<value>ROLE_</value>
-
</property>
-
</bean>
render_code();
这样认证管理器和授权管理器就ok了,别的无论是过滤器还是拦截器都会用到它们两个,因为它们都要验证而这两个就是凭证.
那么那两个访问过滤器呢,先说authenticationProcessingFilter是用于表单登陆的
代码
- <beanid="authenticationProcessingFilter"class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
-
<propertyname="authenticationManager"><refbean="authenticationManager"/></property>
-
<propertyname="authenticationFailureUrl"><value>/failure.html</value></property>
-
<propertyname="defaultTargetUrl"><value>/ok.html</value></property>
-
<propertyname="filterProcessesUrl"><value>/check</value></property>
-
</bean>
render_code();
这样的话加上上面配置的认证管理器就已经可以处理登陆了(注意的是它没有用到授权管理器,因为它只是个访问入口还没有权限的授予)
再说一下HTTP基本认证:它比上面的略复杂一点
需要配置一个
代码
- <beanid="BasicProcessingFilterEntryPoint"class="org.acegisecurity.ui.basicauth.BasicProcessingFilterEntryPoint">
-
<propertyname="realmName"><value>javafish</value></property>
-
</bean>
- 然后
-
<beanid="BasicProcessingFilter"class="org.acegisecurity.ui.basicauth.BasicProcessingFilter">
-
<propertyname="authenticationManager">
-
<refbean="authenticationManager"/>
-
</property>
-
<propertyname="authenticationEntryPoint">
-
<refbean="BasicProcessingFilterEntryPoint"/>
-
</property>
-
</bean>
render_code();
即可.
不过在HTTP基本认证里需要注意的地方是:好多人配置好了怎么看不到效果啊,一开始我也是很郁闷,看了BasicProcessingFilter的源代码:
String header = httpRequest.getHeader("Authorization");//我们一般进入网页测试的时候这里的header始终是null的
代码
- if(logger.isDebugEnabled()){
-
logger.debug("Authorizationheader:"+header);
- }
-
if((header!=null)&&header.startsWith("Basic")){
- .................
render_code();
只有在服务器上配置哪个目录在访问的时候用HTTP基本认证,它才会起作用(一开始还以为是Acegi的BUG呢)
下面说一下真正对URL资源的保护了filterSecurityInterceptor它的本质是个过滤器,有了前面*管理器的基础了这就很容易了:
代码
- <beanid="filterSecurityInterceptor"class="org.acegisecurity.intercept.web.FilterSecurityInterceptor">
-
<propertyname="authenticationManager">
-
<reflocal="authenticationManager"/>
-
</property>
-
<propertyname="accessDecisionManager">
-
<reflocal="accessDecisionManager"/>
-
</property>
-
<propertyname="objectDefinitionSource">
-
<value>
-
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
-
PATTERN_TYPE_APACHE_ANT
-
/ok.html=ROLE_USER
-
</value>
-
</property>
-
</bean>
render_code();
光这样配置还是不够的,因为当授权失败的时候会抛出异常的,我们应该配置一个异常过滤器来捕获它,exceptionTranslationFilter它是用来捕获异常的,看一下配置吧:
代码
- <beanid="exceptionTranslationFilter"class="org.acegisecurity.ui.ExceptionTranslationFilter">
-
<propertyname="authenticationEntryPoint"><reflocal="authenticationProcessingFilterEntryPoint"/></property>
-
<propertyname="accessDeniedHandler">
-
<beanclass="org.acegisecurity.ui.AccessDeniedHandlerImpl">
-
<propertyname="errorPage"value="/failure.html"/>
-
</bean>
-
</property>
-
</bean>
-
<beanid="authenticationProcessingFilterEntryPoint"class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint">
-
<propertyname="loginFormUrl"><value>/Login.html</value></property>
-
<propertyname="forceHttps"><value>false</value></property>
-
</bean>
render_code();
这样就OK了
最后说一下对类中方法的保护:
首先写一个类并在spring中配置好:
代码
- packageorg.li.acegi;
-
publicclassTestAcegi
- {
-
publicvoidRole()
- {
-
System.out.println("javafish");
- }
- }
-
<beanid="testAcegi"class="org.li.acegi.TestAcegi"/>
render_code();
然看写个servlet访问一下它
代码
- packageorg.li.servlet;
-
importjava.io.IOException;
-
importjava.io.PrintWriter;
-
importjavax.servlet.ServletException;
-
importjavax.servlet.http.HttpServlet;
-
importjavax.servlet.http.HttpServletRequest;
-
importjavax.servlet.http.HttpServletResponse;
-
importorg.li.acegi.TestAcegi;
-
importorg.springframework.context.ApplicationContext;
-
importorg.springframework.web.context.support.WebApplicationContextUtils;
-
publicclassTestServletextendsHttpServlet
- {
-
privatestaticfinallongserialVersionUID=-5610016980827214773L;
-
publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)
-
throwsServletException,IOException
- {
-
response.setContentType("text/html;charset=GBK");
- PrintWriterout=response.getWriter();
- ApplicationContextctx=
- WebApplicationContextUtils.getRequiredWebApplicationContext(request.getSession().getServletContext());
-
TestAcegitest=(TestAcegi)ctx.getBean("testAcegi");
-
test.Role();
-
out.println("调用成功");
- }
-
publicvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)
-
throwsServletException,IOException
- {
- doGet(request,response);
- }
- }
render_code();
准备工作做好了,开始配置Acegi
先在Spring里给Acegi做个代理:
代码
- <beanid="autoProxyCreator"class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
-
<propertyname="beanNames">
-
<list>
-
<value>testAcegi</value>
-
</list>
-
</property>
-
<propertyname="interceptorNames">
-
<list>
-
<value>methodSecurityInterceptor</value>
-
</list>
-
</property>
-
</bean>
render_code();
里面的methodSecurityInterceptor呢配置为:
代码
- <beanid="methodSecurityInterceptor"class="org.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor">
-
<propertyname="authenticationManager">
-
<refbean="authenticationManager"/>
-
</property>
-
<propertyname="accessDecisionManager">
-
<refbean="accessDecisionManager"/>
-
</property>
-
<propertyname="objectDefinitionSource">
-
<value>org.li.acegi.TestAcegi.Role=ROLE_USER</value>
-
</property>
-
</bean>
render_code();
这样当直接访问http://localhost:8080/AcegiWeb/servlet/TestServlet的时候会发现不可访问,控件台也不输出”javafish”,当输入正确的用户名和密码之后便可以访问.
这样它就对类的方法调用起了保护的作用,这一点可以把Acegi应用到DWR上效果是很理想的.
对于Acegi有很多的过滤器不用全写在web.xml里,acegi提供了一个特殊的过滤器我们可以写成这样,在Web.xml里:
代码
- <filter>
-
<filter-name>Acegi</filter-name>
-
<filter-class>org.acegisecurity.util.FilterToBeanProxy</filter-class>
-
<init-param>
-
<param-name>targetClass</param-name>
-
<param-value>org.acegisecurity.util.FilterChainProxy</param-value>
-
</init-param>
-
</filter>
-
<filter-mapping>
-
<filter-name>Acegi</filter-name>
-
<url-pattern>/*</url-pattern>
-
</filter-mapping>
-
<context-param>
-
<param-name>contextConfigLocation</param-name>
-
<param-value>
- /WEB-INF/applicationContext.xml
-
</param-value>
-
</context-param>
-
<listener>
-
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
-
</listener>
-
-
<listener>
-
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
-
</listener>
-
<listener>
-
<listener-class>org.acegisecurity.ui.session.HttpSessionEventPublisher</listener-class>
-
</listener>
-
<servlet>
-
<servlet-name>TestServlet</servlet-name>
-
<servlet-class>org.li.servlet.TestServlet</servlet-class>
-
</servlet>
-
<servlet-mapping>
-
<servlet-name>TestServlet</servlet-name>
-
<url-pattern>/servlet/TestServlet</url-pattern>
-
</servlet-mapping>
render_code();
在Spring的配置文件里:
代码
- <beanid="chainProxy"class="org.acegisecurity.util.FilterChainProxy">
-
<propertyname="filterInvocationDefinitionSource">
-
<value>
- CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
- PATTERN_TYPE_APACHE_ANT
- /**=HttpSessionContextIntegrationFilter,authenticationProcessingFilter,BasicProcessingFilter,anonymousProcessingFilter,exceptionTranslationFilter,filterSecurityInterceptor
-
</value>
-
</property>
-
</bean>
render_code();
分享到:
相关推荐
"浅谈Acegi配置 - Spring - Java - JavaEye论坛.mht"很可能深入讨论了Acegi的配置细节,包括如何设置安全性过滤器链,配置不同的访问控制策略,以及如何处理异常情况。在Acegi中,配置是非常关键的,因为它定义了...
`浅谈Acegi配置.mht`系列文件可能探讨了Acegi的配置过程,包括基本的配置元素如`<security:global-method-security>`和`<security:http>`,以及如何定义权限表达式和自定义过滤器。Acegi的配置是其强大之处,但也...
acegi配置文件清单
被解剖的acegi配置文件. 博文链接:https://rmn190.iteye.com/blog/175041
Acegi配置.mhtAcegi配置的相关配置的信息在里面有一些
在 Acegi 配置指南中,我们主要关注如何设置和配置 Acegi 框架来保护 Web 应用程序的安全。 首先,我们需要在 `web.xml` 文件中配置 Acegi 的过滤器。在示例代码中,定义了一个名为 `Acegi Filter Chain Proxy` 的...
在本文中,我们将深入探讨Acegi的详细配置,并通过实际示例来理解其工作原理。 首先,我们要明白Acegi的核心功能是提供身份验证(Authentication)和授权(Authorization)服务。身份验证是确认用户的身份,而授权...
- "aopacegi"可能是一个包含Acegi与AOP相关配置或实现的文件,可能涉及切面的定义和安全策略的配置。 Acegi Security在过去的开发实践中扮演了重要角色,它的设计理念和实现方式对后来的安全框架产生了深远影响。...
在配置Acegi时,首先需要在`web.xml`文件中定义一个名为`Acegi Filter Chain Proxy`的过滤器。这个过滤器是Acegi安全机制的核心,它负责拦截所有请求并根据配置执行相应的安全策略。下面是一段典型的`web.xml`配置...
在本实例中,我们将探讨Acegi Security的配置、详细设置以及如何通过代码实现其功能。 首先,让我们理解Acegi Security的核心概念。该框架提供了一种基于角色的访问控制(RBAC)机制,允许开发人员定义用户权限并...
Acegi 安全框架是Spring生态中的一个早期的安全组件,它提供了一套强大的基于数据库的配置来实现应用程序的安全策略。本资源由王政创作并分享,主要涉及如何将XML配置转换为数据库动态配置,这对于那些需要灵活管理...
### Acegi的详细配置实现 #### 一、整体架构概览 **Acegi Security** 是一个为Spring框架设计的安全管理工具,它提供了丰富的安全服务,包括认证(Authentication)、授权(Authorization)以及会话管理(Session ...
Acegi是一个专门为SpringFramework应用提供安全机制的开放源代码项目,全称为Acegi Security System for ...通过这个例子详细介绍如何配置Acegi的各个组件,同时介绍如何扩展Acegi 使其能够从数据库中读取配置信息。
在《实战Acegi:使用Acegi作为基于Spring框架的WEB应用的安全框架.pdf》中,可能会详细讲解如何配置和使用Acegi。以下是一些关键步骤: 1. **添加依赖**:首先,在项目中引入Acegi的依赖库,通常是通过Maven或...
在Spring Acegi中,安全配置通常通过XML配置文件完成,但也可以使用注解进行简化。配置包括定义访问控制规则、配置认证和授权策略,以及设置安全过滤器链。 例如,以下是一个简单的XML配置示例,定义了一个URL访问...
1. **Acegi例子代码**:这个例子代码可能包含了一个简单的Spring应用,演示了如何配置和使用Acegi进行安全控制。通过运行此示例,你可以了解Acegi的配置过程以及如何在实际应用中集成。 2. **学习网址**:提供了一...
jar包 博文链接:https://fengzgxing.iteye.com/blog/248761