- 浏览: 183952 次
- 性别:
- 来自: 青岛
-
文章分类
最新评论
-
loveminer:
...
权限控制 -
killerover85:
在企业项目中如何用
weblogic ThreadPool has stuck threads -
just4you:
这排版和背景色看着真蛋疼
spring 安全框架 -
zfms:
-XX:-UseGCOverheadLimit
具体有什么 ...
java.lang.OutOfMemoryError: GC overhead limit exceeded
浅谈Acegi配置
Acegi Security System 是一种功能强大并易于使用的替代性方案,使您不必再为 Java 企业应用程序编写大量的安全代码。虽然它专门针对使用 Spring 框架编写的应用程序,但是任何类型的 Java 应用程序都没有理由不去使用 Acegi。
本文的主要目的是希望能够说明如何在基于Spring构架的Web应用中使用Acegi,而不是详细介绍其中的每个接口、每个类。注意,即使对已经存在的Spring应用,通过下面介绍的步骤,也可以马上享受到Acegi提供的认证和授权。
Acegi Security System 使用安全过滤器来提供企业应用程序的身份验证和授权服务。该框架提供了不同类型的过滤器,可以根据应用程序的需求进行配置。您将在本文后面了解到 安全过滤器的不同类型 ;现在,只需注意可以为如下任务配置 Acegi 安全过滤器:
- 在访问一个安全资源之前提示用户登录。
- 通过检查安全标记(如密码),对用户进行身份验证。
- 检查经过身份验证的用户是否具有访问某个安全资源的特权。
- 将成功进行身份验证和授权的用户重定向到所请求的安全资源。
- 对不具备访问安全资源特权的用户显示 Access Denied 页面。
- 在服务器上记录成功进行身份验证的用户,并在用户的客户机上设置安全 cookie。使用该 cookie 执行下一次身份验证,而无需要求用户登录。
- 将身份验证信息存储在服务器端的会话对象中,从而安全地进行对资源的后续请求。
- 在服务器端对象中构建并保存安全信息的缓存,从而优化性能。
- 当用户退出时,删除为用户安全会话而保存的服务器端对象。
- 与大量后端数据存储服务(如目录服务或关系数据库)进行通信,这些服务用于存储用户的安全信息和 ECM 的访问控制策略。
正如这个列表显示的那样,Acegi 的安全过滤器允许您执行保护企业应用程序所需的几乎任何事情。
[基础工作]
在你的Web应用的lib中添加Acegi下载包中的acegi-security.jar
[web.xml]
在web.xml配置
- <filter>
- <filter-name>Acegi Filter Chain Proxy</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>限定了FilterToBeanProxy 的URL匹配模式 ,
- <filter-mapping>
- <filter-name>Acegi Filter Chain Proxy</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
<listener>的HttpSessionEventPublisher 用于发布HttpSessionApplicationEvents 和HttpSessionDestroyedEvent 事件给spring的applicationcontext 。
- <listener>
- <listener-class>
- org.acegisecurity.ui.session.HttpSessionEventPublisher
- </listener-class>
- </listener>
[applicationContext-acegi-security.xml]
applicationContext-acegi-security.xml文件配置
FilterChainProxy 会按顺序来调用这些filter,使这些filter能享用Spring ioc的功能 , CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON定义了url比较前先转为小写, PATTERN_TYPE_APACHE_ANT定义了使用Apache ant的匹配模式
- <bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy">
- <property name="filterInvocationDefinitionSource">
- <value>
- CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
- PATTERN_TYPE_APACHE_ANT
- /**=httpSessionContextIntegrationFilter, logoutFilter, authenticationProcessingFilter,
- basicProcessingFilter,rememberMeProcessingFilter,anonymousProcessingFilter,
- switchUserProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor
- </value>
- </property>
- </bean>
定义数据源为调用tomcat容器数据源 登入验证时需要获取数据源连接数据库
- <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
- <property name="jndiName"><value>java:/comp/env/jdbc/test</value></property>
- </bean>
认证管理 ,从数据库中读取用户信息验证身份
- <bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager">
- <property name="providers">
- <list>
- <ref local="daoAuthenticationProvider"/>
- </list>
- </property>
- </bean>
daoAuthenticationProvider
进行简单的基于数据库的身份验证。DaoAuthenticationProvider 获取数据库中的账号密码并进行匹配,若成功则在通过用户身份的同时返回一个包含授权信息的Authentication对象 ,否则身份验证失败,抛出一个AuthenticatiionException 。
- <bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
- <property name="userDetailsService"><ref local="jdbcDaoImpl"/></property>
- <property name="passwordEncoder"><ref local="passwordEncoder"/></property>
- <property name="userCache"><ref local="userCache"/></property>
- </bean>
jdbcDaoImpl
用于在数据中获取用户信息
- <bean id="jdbcDaoImpl" class="com.milesup.acegi.userdetails.jdbc.JdbcDaoImpl">
- <property name="dataSource"><ref bean="dataSource"/></property>
- <property name="rolePrefix"><value>ROLE_</value></property>
- </bean>
passwordEncoder
使用加密器对用户输入的明文进行加密。Acegi提供了三种加密器:
- 1 : PlaintextPasswordEncoder—默认,不加密,返回明文.
- 2 : ShaPasswordEncoder—哈希算法(SHA)加密
- 3 : Md5PasswordEncoder—消息摘要(MD5)加密
使用加密器对用户输入的明文进行加密 为MD5加密方式
缓存用户和资源相对应的权限信息。每当请求一个受保护资源时,daoAuthenticationProvider 就会被调用以获取用户授权信息 。如果每次都从数据库获取的话,那代价很高,对于不常改变的用户和资源信息来说,最好是把相关授权信息缓存起来。
userCache提供了两种实现: NullUserCache 和EhCacheBasedUserCache , NullUserCache 实际上就是不进行任何缓存,EhCacheBasedUserCache 是使用Ehcache来实现缓功能。
- <!-- 缓存管理 -->
- <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"/>
- <!-- 缓存用户和资源相对应的权限信息 -->
- <bean id="userCacheBackend" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
- <property name="cacheManager">
- <ref local="cacheManager"/>
- </property>
- <property name="cacheName">
- <value>userCache</value>
- </property>
- </bean>
- <bean id="userCache" class="org.acegisecurity.providers.dao.cache.EhCacheBasedUserCache">
- <property name="cache"><ref local="userCacheBackend"/></property>
- </bean>
该过滤器用来处理在系统认证授权过程中抛出的异常
- <bean id="exceptionTranslationFilter" class="org.acegisecurity.ui.ExceptionTranslationFilter">
- <property name="authenticationEntryPoint"><ref local="authenticationProcessingFilterEntryPoint"/></property>
- </bean>
一个没有进行身份验证的用户试图访问受保护的资源验证是否授权 Exception Translation Filter(ETF)
- <bean id="authenticationProcessingFilterEntryPoint" class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint">
- <property name="loginFormUrl"><value>/login.jsp</value></property>
- <property name="forceHttps"><value>false</value></property>
- </bean>
登入验证
成功进入main.jsp页面 ,失败跳转到/login.jsp?login_error=1 ,登入url为 /j_acegi_security_check, Authentication Processing Filter(APF)
authenticationFailureUrl 定义登陆失败时转向的页面
defaultTargetUrl 定义登陆成功时转向的页面
filterProcessesUrl 定义登陆请求的页面
rememberMeServices 用于在验证成功后添加cookie信息
- <bean id="authenticationProcessingFilter" class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
- <property name="authenticationManager"><ref bean="authenticationManager"/></property>
- <property name="authenticationFailureUrl"><value>/login.jsp?login_error=1</value></property>
- <property name="defaultTargetUrl"><value>/main.jsp</value></property>
- <property name="filterProcessesUrl"><value>/j_acegi_security_check</value></property>
- <property name="rememberMeServices"><ref local="rememberMeServices"/></property>
- </bean>
- 用于处理HTTP头的认证信息,如从<span style="color: #0000ff;"><strong>Spring远程协议</strong>
- </span>
- (如Hessian和Burlap)或<span style="color: #0000ff;"><strong>普通的浏览器如IE,Navigator的HTTP头</strong>
- </span>
- 中获取用户
- 信息,将他们转交给通过<span style="text-decoration: underline;">authenticationManager</span>
- 属性装配的认证管理器。如果认证成功,会<span style="text-decoration: underline;">将一个Authentication对象放到会话中</span>
- ,否则,如果认证失败,会将控制<span style="text-decoration: underline;">转交给认证入口点</span>
- (通过authenticationEntryPoint属性装配)
- <!-- 用于处理HTTP头的认证信息 -->
- <bean id="basicProcessingFilter" class="org.acegisecurity.ui.basicauth.BasicProcessingFilter">
- <property name="authenticationManager"><ref local="authenticationManager"/></property>
- <property name="authenticationEntryPoint"><ref local="basicProcessingFilterEntryPoint"/></property>
- </bean>
- <!-- 通过向浏览器发送一个HTTP401(未授权)消息,提示用户登录 -->
- <bean id="basicProcessingFilterEntryPoint" class="org.acegisecurity.ui.basicauth.BasicProcessingFilterEntryPoint">
- <property name="realmName"><value>Milesup Realm</value></property>
- </bean>
注销 退出验证 跳转到/login.jsp
- <bean id="logoutFilter" class="org.acegisecurity.ui.logout.LogoutFilter">
- <constructor-arg value="/login.jsp"/><constructor-arg>
- <list>
- <bean class="org.acegisecurity.ui.logout.SecurityContextLogoutHandler"/>
- </list>
- </constructor-arg>
- </bean>
经过投票 机制来决定是否可以访问某一资源(URL 或方法 )。allowIfAllAbstainDecisions为false时如果有一个或以上的decisionVoters投票通过,则授权通过。可选的决策机制有ConsensusBased和UnanimousBased
roleVoter
必须是以rolePrefix设定的value开头的权限才能进行投票,如 ROLE_
- <bean id="roleVoter" class="org.acegisecurity.vote.RoleVoter">
- <property name="rolePrefix">
- <value>ROLE_</value>
- </property>
- </bean>
- <!-- 组件管理授权过程 决策管理器-->
- <bean id="httpRequestAccessDecisionManager" class="org.acegisecurity.vote.AffirmativeBased">
- <property name="allowIfAllAbstainDecisions"><value>false</value></property>
- <property name="decisionVoters">
- <list>
- <ref bean="roleVoter"/>
- </list>
- </property>
- </bean>
过滤器安全拦截器 是否认证,是否有权限访问受保护的资源
在执行转向url前检查objectDefinitionSource 中设定的用户权限信息。首先,objectDefinitionSource 中定义了访问URL需要的属性信息(这里的属性信息仅仅是标志,告诉accessDecisionManager 要用哪些voter来投票)。然后,authenticationManager 掉用自己的provider来对用户的认证信息进行校验。最后,有投票者根据用户持有认证和访问url需要的属性,调用自己的voter来投票,决定是否允许访问。
- <bean id="filterInvocationInterceptor" class="org.acegisecurity.intercept.web.FilterSecurityInterceptor">
- <property name="authenticationManager"><ref bean="authenticationManager"/></property>
- <property name="accessDecisionManager"><ref local="httpRequestAccessDecisionManager"/></property>
- <property name="objectDefinitionSource">
- <value>
- PATTERN_TYPE_APACHE_ANT
- /user.jsp=ROLE_ADMIN
- /admin=ROLE_ADMIN
- </value>
- </property>
- </bean>
[login.jsp]
- <form action="/j_acegi_security_check" method="post" >
- <table>
- <tr>
- <td width="140" height="22" align="right">用户名</td>
- <td width="47%" align="left"><input value="${lastUserName}" name="j_username" type="text" class="inputstyle" id="j_username"></td>
- <td align="left" nowrap><div class="loginmeon"> </div></td>
- </tr>
- <tr>
- <td width="140" height="22" align="right">密 码</td>
- <td width="47%" align="left"><input name="j_password" type="password" class="inputstyle" id="j_password" size="21"></td>
- </tr>
- <tr>
- <td height="60" colspan="3" align="center" valign="middle">
- <input type="submit" name="imageField2" value="登入"></td>
- </tr>
- </table>
- </td>
- </tr>
- </table>
- </td>
- </tr>
- </table>
- </form>
[JdbcDaoImpl.java]
- public class JdbcDaoImpl extends org.acegisecurity.userdetails.jdbc.JdbcDaoImpl {
- private String anonymousRoleName = "ROLE_ANONYMOUS";
- private Log logger = LogFactory.getLog(JdbcDaoImpl.class);
- private PreparedStatement userPstmt;
- private PreparedStatement rolePstmt;
- public UserDetails loadUserByUsername(String userName)
- throws UsernameNotFoundException, DataAccessException {
- UserDetails user = findUserByName(userName);
- if (user == null) {
- throw new UsernameNotFoundException("User not found");
- }
- return user;
- }
- private UserDetails findUserByName(String userName) {
- Connection connection = null;
- ResultSet rsUser = null;
- ResultSet rsRole = null;
- UserDetails user = null;
- String logonName = null;
- String password = null;
- String roleName = null;
- int status = -1;
- boolean enabled = false;
- Vector roles = null;
- GrantedAuthority[] rolesArray = null;
- try {
- connection = getDataSource().getConnection();
- userPstmt = connection
- .prepareStatement("select * from users where user_NAME=?");
- userPstmt.setString(1, userName);
- rsUser = userPstmt.executeQuery();
- if (rsUser.next()) {
- logonName = rsUser.getString("USER_NAME");
- password = rsUser.getString("PASSWORD");
- status = rsUser.getInt("STATUS");
- if (status == 1)
- enabled = true;
- } else {
- return null;
- }
- rolePstmt = connection
- .prepareStatement("SELECT ROLE.NAME Role FROM ROLE, users_ROLES, users WHERE ROLE.ID= user_ROLES.FK_ROLES and users.user_NAME=?");
- rolePstmt.setString(1, userName);
- rsRole = rolePstmt.executeQuery();
- roles = new Vector();
- while (rsRole.next()) {
- roleName = getRolePrefix() + rsRole.getString("Role");
- roles.add(new GrantedAuthorityImpl(roleName));
- }
- rolesArray = new GrantedAuthority[roles.size() + 1];
- int index = 0;
- for (index = 0; index < roles.size(); index++)
- rolesArray[index] = (GrantedAuthority) roles.get(index);
- rolesArray[index] = new GrantedAuthorityImpl(anonymousRoleName);
- user = new User(logonName, password, enabled, true, true, true,
- rolesArray);
- } catch (SQLException e) {
- logger.fatal("", e);
- } finally {
- try {
- rsRole.close();
- rsUser.close();
- userPstmt.close();
- rolePstmt.close();
- connection.close();
- } catch (SQLException sqlx) {
- logger.fatal("", sqlx);
- } catch (NullPointerException x) {
- logger.fatal("", x);
- }
- }
- return user;
- }
- }
相关推荐
"浅谈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