目前acegi(Spring Security)主要是针对简化Java EE企业级应用中安全的开发和部署而来的!acegi采纳了Spring Framework来架构自身,并在后来成为了spring官方的子项目,即Spring Security。
因此我们建议acegi作用的目标应用最好是基于spring Framework开发的
实例介绍:
本实例是基于acegi开发的,在index.jsp页面中,提供了securedpage.jsp页面的html超链接,一旦用户点击它,就会弹出登陆对话框(HTTP BASIC认证)。然后,开发者提供相应的用户凭证,才能够进入受保护的页面。
两个web页面:
index.jsp
<%@ page session="false" pageEncoding="GBK" contentType="text/html; charset=GBK" %> <title>acegifirstdemo应用首页</title> <html> <body> <a href="securedpage.jsp">受保护的页面(securedpage.jsp)</a> </body> </html>
|
securedpage.jsp
<%@ page session="false" pageEncoding="GBK" contentType="text/html; charset=GBK" %> <title>acegifirstdemo应用securedpage页面</title> <html> <body> 欢迎您的到来到securedpage.jsp,回 <a href="index.jsp">首页</a> </body> </html>
|
在web.xml中配置spring和acegi过滤器(由于acegi本身就是基于过滤器驱动的)
//
contextConfigLocation /WEB-INF/classes/applicationContext.xml //过滤器的定义 Acegi Filter Chain Proxy org.acegisecurity.util.FilterToBeanProxy targetBean filterChainProxy //拦截所有的web访问 Acegi Filter Chain Proxy /*
org.springframework.web.context.ContextLoaderListener
|
最后要配置受管filterChainProxy对象.在ApplicationContext.xml中定义!它引用了四个过滤器:
<bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy"> <property name="filterInvocationDefinitionSource"> <value> PATTERN_TYPE_APACHE_ANT /**=httpSessionContextIntegrationFilter,basicProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor </value> </property>
</bean>
|
第一个过滤器:httpSessionContextIntegrationFilter负责完成Acegi SecurityContext的同步,它会同Http Session交互,如果当前的Http Session实例已经存在,而且存放了以前的认证信息,则HttpSessionContextIntegrationFilter会负责将存储在session中的认证信息还原到SecurityContext中,在退出这一过滤器时候,它会清除当前线程中的SecurityContext相关信息,并将修改过的SecurityContext同步到已创建的Http Session对象中。
<bean id="httpSessionContextIntegrationFilter" class="org.acegisecurity.context.HttpSessionContextIntegrationFilter"> <property name="allowSessionCreation" value="false" /> </bean>
|
第二个过滤器:basicProcessingFilter负责完成用户的认证。当用户访问的web资源受到保护时,这个过滤器便会介入进来,当访问受到保护的web资源时,如果用户已经在http请求头信息中提供了相应的用户凭证信息,则basicProcessingFilter会调用相应的认真管理器(ProviderManager)。如果认证不成功,或者用户根本就没有提供凭证信息,该用户访问的资源又受到acegi的保护,则这一过滤器会调用basicProcessingFilter构造http响应头信息,浏览器在收到响应信息后会弹出对话框要求用户输入用户名和密码,用户管理器在认证过程中,会将请求委托给相应的dao认证提供者!这里使用简单的基于内存的InMemoryDaoImpl类,InMemoryDaoImpl对象会采用‘用户名=密码,角色集合,启用标志位’形式来存储用户和角色的信息。
<bean id="basicProcessingFilter" class="org.acegisecurity.ui.basicauth.BasicProcessingFilter"> <property name="authenticationManager" ref="authenticationManager" /> <property name="authenticationEntryPoint" ref="basicProcessingFilterEntryPoint" /> </bean>
class="org.acegisecurity.ui.basicauth.BasicProcessingFilterEntryPoint">
class="org.acegisecurity.providers.ProviderManager">
class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
class="org.acegisecurity.userdetails.memory.InMemoryDaoImpl"> admin=password,ROLE_MANAGER
|
第三个过滤器:exceptionTranslationFilter负责处理认证和授权过程中出现的异常。
<bean id="exceptionTranslationFilter" class="org.acegisecurity.ui.ExceptionTranslationFilter"> <property name="authenticationEntryPoint" ref="basicProcessingFilterEntryPoint" /> <property name="createSessionAllowed" value="false" /> </bean>
|
第四个过滤器:FilterSecurityInterceptor负责完成用户的授权。
<bean id="filterInvocationInterceptor" class="org.acegisecurity.intercept.web.FilterSecurityInterceptor"> <property name="authenticationManager" ref="authenticationManager" /> <property name="accessDecisionManager" ref="httpRequestAccessDecisionManager" /> <property name="objectDefinitionSource"> <value> PATTERN_TYPE_APACHE_ANT /securedpage.jsp=ROLE_ADMIN </value> </property> </bean>
<bean id="httpRequestAccessDecisionManager" class="org.acegisecurity.vote.AffirmativeBased"> <property name="decisionVoters"> <list> <ref bean="roleVoter" /> </list> </property> </bean>
<bean id="roleVoter" class="org.acegisecurity.vote.RoleVoter" />
|
最后,配置logger监听器,可以查看acegi认证和授权信息
//监听各种用户认证事件
<bean id="authenticationLoggerListener" class="org.acegisecurity.event.authentication.LoggerListener" />
//监控各种用户授权事件 class="org.acegisecurity.event.authorization.LoggerListener"/>
|
完整的ApplicationContext.xml配置:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="" xmlns:xsi="" xsi:schemaLocation=" /spring-beans-2.0.xsd">
<bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy"> <property name="filterInvocationDefinitionSource"> <value> PATTERN_TYPE_APACHE_ANT /**=httpSessionContextIntegrationFilter,basicProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor </value> </property> </bean> <bean id="httpSessionContextIntegrationFilter" class="org.acegisecurity.context.HttpSessionContextIntegrationFilter"> <property name="allowSessionCreation" value="false" /> </bean> <bean id="basicProcessingFilter" class="org.acegisecurity.ui.basicauth.BasicProcessingFilter"> <property name="authenticationManager" ref="authenticationManager" /> <property name="authenticationEntryPoint" ref="basicProcessingFilterEntryPoint" /> </bean>
<bean id="basicProcessingFilterEntryPoint" class="org.acegisecurity.ui.basicauth.BasicProcessingFilterEntryPoint"> <property name="realmName" value="Acegi First Demo Realm" /> </bean> <bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager"> <property name="providers"> <list> <ref local="daoAuthenticationProvider" /> </list> </property> </bean>
<bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider"> <property name="userDetailsService" ref="inMemDaoImpl" /> </bean> <bean id="inMemDaoImpl" class="org.acegisecurity.userdetails.memory.InMemoryDaoImpl"> <property name="userMap"> <value>admin=password,ROLE_MANAGER</value> </property> </bean>
<bean id="exceptionTranslationFilter" class="org.acegisecurity.ui.ExceptionTranslationFilter"> <property name="authenticationEntryPoint" ref="basicProcessingFilterEntryPoint" /> <property name="createSessionAllowed" value="false" /> </bean>
<bean id="filterInvocationInterceptor" class="org.acegisecurity.intercept.web.FilterSecurityInterceptor"> <property name="authenticationManager" ref="authenticationManager" /> <property name="accessDecisionManager" ref="httpRequestAccessDecisionManager" /> <property name="objectDefinitionSource"> <value> PATTERN_TYPE_APACHE_ANT /securedpage.jsp=ROLE_ADMIN </value> </property> </bean>
<bean id="httpRequestAccessDecisionManager" class="org.acegisecurity.vote.AffirmativeBased"> <property name="decisionVoters"> <list> <ref bean="roleVoter" /> </list> </property> </bean>
<bean id="roleVoter" class="org.acegisecurity.vote.RoleVoter" /> <bean id="authenticationLoggerListener" class="org.acegisecurity.event.authentication.LoggerListener" />
<bean id="authorizationLoggerListener" class="org.acegisecurity.event.authorization.LoggerListener"/> </beans>
|
商业性 Web 站点大都提供站点认证功能以保护某些受限资源,HTTP 协议和 J2EE 规范对 Web 站点的认证过程都已有了详尽的定义,常见浏览器都能根据相应协议提供对应的界面形式帮助用户完成站点的认证过程
出于安全性的需要和用户授权管理的考虑,常见的 J2EE 站点对特定资源都会加入认证/授权机制。例如一个公网上的论坛,一个只对特定用户开放的 RSS 或 Atom Feed,这些资源都必须在确信访问者为被授权用户时才能向访问者开放。为了实现这样的功能,J2EE 站点通常会采用某种站点认证机制,其中常见的有 HTTP Basic 认证和 J2EE Form-Based 认证。
HTTP Basic 认证是 HTTP 认证协议(rfc2617)所定义的标准认证方式。要求 HTTP Basic 认证的服务器会在客户端访问受保护资源时向客户端发出请求,要求客户端上传用户名和密码对。服务器在收到用户名/密码并验证通过后,才将保护资源的内容返回给客户端。
HTTP Basic 认证方式使用 base64 编码方式传送用户名和密码,而 base64 仅仅是一种公开的编码格式而非加密措施,因而如果信道本身不使用 SSL 等安全协议,用户密码较容易被截获。
Form-Based 认证不同于 HTTP Basic 认证,它是 J2EE 对于认证方式的一种扩展。它使用自定义的 HTML 表单(通常为 login.jsp)作为输入用户名和密码的用户界面,最终将用户在表单上填入的用户名/密码提交至服务器。
Form-Based 认证方式在 J2EE 站点中更为常见。这一方面是由于它提供了自定义的用户名密码输入界面;另一方面它的传输也更为安全,通常情况下 login.jsp 会被配置为需要使用 SSL 信道访问,这样在步骤 2、3 中对用户名和密码的传送就被安全信道所保护,而较难被非法截取。
阅读(5234) | 评论(1) | 转发(0) |