属性userMap使用一个org.acegisecurity.userdetails.memory.UserMap对象来定义一组用户名、密码和权限。幸运的是,当装配一个InMemoryDaoImpl时,你不必为配置一个UserMap实例而操心,因为Acegi提供了一个属性编辑器,它能够帮你把一个字符串转化为一个UserMap对象。
以上的 authenticationDao声明中定义了三个用户:palmerd、bauerj、myersn。这三个用户的密码分别是4moreyears,ineedsleep和traitor。用户palmerd被定义为拥有权限ROLE_PRESIDENT,bauerj被赋予权限ROLE_FIELD_OPS和ROLE_DIRECTOR,并且用户myersn被给予ROLE_CENTRAL_OPS授权。
JdbcDaoImpl是一个简单而灵活的认证DAO。以它最简单的形势,只需要一个javax.sql.DataSource对象的引用,可以通过以下方式在Spring配置文件中进行声明:
- <bean id="authenticationDao"
- class="org.acegisecurity.userdetails.jdbc.JdbcDaoImpl">
- <property name="dataSource">
- <ref bean="dataSource"/>
- property>
- bean>
JdbcDaoImpl假设你在数据库中已经建立了某些用于存放用户信息的表。特别地,它假设有一张“Users”表和一张“授权”表,如图:
当JdbcDaoImpl查找用户信息时,它会使用“SELECT username,password,enabled FROM users WHERE username = ?”作为查询语句。类似地,当查找授权时,它会使用“SELECT username,authority FROM authorities WHERE username = ?”。
尽管JdbcDaoImpl假定的表结构非常直接,它们很可能与你已经为应用系统建立的表结构不一致。比如,在Spring培训应用中,Student表保存用户名(在login列中)和密码。是否这意味着你无法在Spring培训应用中使用JdbcDaoImpl来验证学生的身份?
当然不是。但你必须通过设置usersByUserNameQuery属性告诉JdbcDaoImpl如何找到用户信息。下面是对authenticationDao Bean的调整使它更适合Spring培训应用:
- <bean id="authenticationDao"
- class="org.acegisecurity.userdetails.jdbc.JdbcDaoImpl">
- <property name="dataSource">
- <ref bean="dataSource"/>
- property>
- <property name="usersByUserNameQuery">
- <value>
- SELECT login,password FROM student WHERE login=?
- value>
- property>
- bean>
现在JdbcDaoImpl知道如何在Student表中查找用户的认证信息了。但是,还有一件事遗漏了。Student表中没有标志表明用户是否被禁用。事实上,我们一直假设所有的学生都是未被禁用的。但我们如何告诉JdbcDaoImpl做同样的假设?
JdbcDaoImpl还有一个usersByUserNameMapping属性,它引用一个MappingSqlQuery实例。MappingSqlQuery的mapRow()方法将一个ResultSet中的字段映射为一个领域对象。对于JdbcDaoImpl,提供给usersByUserNameMapping属性的MappingSqlQusery对象要求能够将一个ResultSet(通过执行用户查询获得)转化为一个
org.acegisecurity.userdetails.UserDetails对象。
UsersByUserNameMapping显示了一个MappingSqlQuery的实现,它适合将学生用户表的一个查询结果转换为一个UserDetails对象。它从ResultSet中抽取出username和password,但总是设置enabled属性为true。
- public class UsersByUsernameMapping extends MappingSqlQuery{
- protected UsersByUsernameMapping(DataSource dataSource){
- super(dataSource,usersByUsernameQuery);
- declareParameter(new SqlParameter(Types.VARCHAR));
- compile();
- }
- protected Object mapRow(ResultSet rs,int rownum) throws SQLException{
- String username=rs.getString(1);
- String password=rs.getString(2);
-
- UserDetails user=new User(username,password,true,
- new GrantedAuthority[]{new GrantedAuthorityImpl("HOLDER")});
- return user;
- }
- }
剩下唯一需要做的事就是声明一个UsersByUsernameMapping Bean,并将它装配到usersByUserNameMapping属性中。以下的authenticationDao Bean的声明将一个内部Bean装配至usersByUserNameMapping属性中,从而可以应用新的用户映射:
- <bean id="authenticationDao"
- class="org.acegisecurity.userdetails.jdbc.JdbcDaoImpl">
- <property name="dataSource">
- <ref bean="dataSource"/>
- </property>
- <property name="usersByUserNameQuery">
- <value>
- SELECT login,password FROM student WHERE login=?
- </value>
- </property>
- <property name="usersByUserNameMapping">
- <bean class="my.UsersByUsernameMapping"/>
- </property>
- </bean>
你也能改变 JdbcDaoImpl查询用户权限的方式。与属性usersByUserNameQuery和usersByUserNameMapping定义JdbcDaoImpl如何查询用户认证信息相同,属性authoritiesByUserNameQuery和authoritiesByUserNameMapping告诉JdbcDaoImpl如何查询用户的权限:例如,你可以使用以下代码从user_privileges表中查询已授予一个用户的权限。
- <bean id="authenticationDao"
- class="org.acegisecurity.userdetails.jdbc.JdbcDaoImpl">
- <property name="dataSource">
- <ref bean="dataSource"/>
- </property>
- <property name="usersByUserNameQuery">
- <value>
- SELECT login,password FROM student WHERE login=?
- </value>
- </property>
- <property name="usersByUserNameMapping">
- <bean class="my.UsersByUsernameMapping"/>
- </property>
- <property name="authoritiesByUserNameQuery">
- <value>
- SELECT login,privilege FROM user_privileges where login=?
- </value>
- </property>
- </bean>
你可以将属性authoritiesByUserNameMapping设置成一个定制的MappingSqlQuery对象,从而可以定制权限查询的结果如何映射为一个org.acegisecurity.GrantedAuthority对象。但是,由于默认的MappingSqlQuery对上面给出的查询来说已经足够了,我们就不再画蛇添足了。
使用加密的密码
默认地,DaoAuthenticationProvider假设用户的密码是以明文方式(未加密的方式)存储的。但在与数据库中取出的密码进行比较之前,可以使用一个密码编码器加密用户输入的明文密码。下面介绍Acegi提供的三个密码编码器:
1. 默认) 不对密码进行编码,直接返回未经改变的密码;PlaintextPasswordEncoder(
2. 对密码进行消息摘要(MD5)加密;Md5PasswordEncoder
3. 对密码进行安全哈希算法(SHA)编码。ShaPasswordEncoder
你可以通过设置DaoAuthenticationProvider的passwordEncoder属性改变它的密码编码器。例如,要使用MD5编码可以用以下代码:
<property name="passwordEncoder""></property>
<bean class="org.acegisecurity.providers.encoding.Md5PasswordEncoder"></bean>
你也需要设置编码器的种子源(salt source)。一个种子源为编码提供种子(salt),或者称编码的密钥。下面是Acegi提供的两个种子源:
1. 使用用户的User对象中某个指定的属性来获取种子;ReflectionSaltSource
2. 对系统中所有用户使用相同的种子。SystemWideSaltSource
SystemWideSaltSource适用于大多数情形。以下一段XML将一个SystemWideSaltSource装配到DaoAuthenticationProvider的saltSource属性中:
- <property name=saltSource">
- <bean class="org.acegisecurity.providers.dao.salt.SystemWideSaltSource">
- <property name="systemWideSalt">
- <value>123abcvalue>
- property>
- bean>
- property>
(这个种子其实就是在原由的字符串后追加上这个指定的字符串,然后再叫给Md5加密)
ReflectionSaltSource使用用户对象的某个特定属性作为用户密码的编码种子。由于这意味着每个用户的密码都会以不同的方式编码,因此更安全。若要装配一个ReflectionSaltSource,可以通过如下方式将它装配到saltSource属性中:
- <property name=saltSource">
- <bean class="org.acegisecurity.providers.dao.salt.ReflectionSaltSource">
- <property name="userPropertyToUse">
- <value>userNamevalue>
- property>
- bean>
- property>
-
在这里,用户的userName属性被用作种子来加密用户的密码。要特别重视的是必须保证种子是静态的,永远不会改变;否则,一旦种子改变,就再也不可能对用户身份进行验证了,因为MD5是不可逆的。
缓存用户信息
每次当请求一个受保护的资源时,认证管理起就被调用以获取用户的安全信息。但如果获取用户信息涉及到查询数据库,每次都查询相同的数据可能在性能上表现得很糟糕。注意到用户信息不会频繁改变,也许更好的做法是在第一次查询时缓存用户信息,并在后续的查询中直接从缓存中获取用户信息。
DaoAuthenticationProvider通过org.acegisecurity.providers.dao.UserCache接口的实现类支持对用户信息进行缓存。
- public interface UserCache {
- UserDetails getUserFromCache(String username);
- void putUserInCache(UserDetails user);
- void removeUserFromCache(String username);
- }
顾名思义,接口UserCache中方法提供了向缓存中放入、取得和删除用户明细信息的功能。写一个你自己的UserCache实现类是相当简单的。然而,在你考虑开发自己的UserCache实现类之前,应该首先考虑Acegi提供的两个方便的UserCache实现类:
1. org.acegisecurity.providers.dao.cache. NullUserCache
2. org.acegisecurity.providers.dao.cache. EhCacheBasedUserCache
NullUserCache事实上不进行任何缓存。任何时候调用它的getUserFromCache方法,得到的返回值都是null。这是DaoAuthenticationProvider使用的默认UserCache实现。
EhCacheBasedUserCache是一个更实用的缓存实现。类如其名,它是基于开源项目ehcache实现的。Ehcache是一个简单快速的针对Java的缓存解决方案,同时也是Hibernate默认的和推荐的缓存方案。
在DaoAuthenticationProvider中使用ehcache是很简单的,只需要简单地声明一个EhCacheBasedUserCase Bean即可:
- <bean id=userCache"
- class="org.acegisecurity.providers.dao.cache. EhCacheBasedUserCache">
- <property name="minutesToIdle">15property>
- bean>
属性minutesToIdle告诉缓存器一条用户信息在没有访问的情况下应该在缓存中保存多久。这里,我们设定在15分钟的非活动期后删除该条用户信息。
声明了userCache Bean之后,下面唯一要做的事就是把它装配到DaoAuthenticationProvider的userCache属性中:
- <bean id="authenticationProvider"
- class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
- <property name="userCache">
- <ref bean="userCache"/>
- property>
- bean>
2.3根据LDAP仓库进行身份验证(未完,代续)
2.4基于Acegi和Yale CAS实现单次登录(未完,代续)
相关推荐
而Acegi Security是Spring社区早期的一个安全模块,它提供了全面的身份验证、授权和会话管理功能,为基于Spring的应用程序提供了强大的安全性支持。本实战教程将深入探讨如何将Acegi Security集成到Spring框架中,...
1. **身份验证**:Acegi支持多种身份验证机制,如基于表单的登录、HTTP基本认证、SSL客户端证书等。你可以根据需求选择适合的认证方式。例如,通常我们会创建一个登录页面,用户输入用户名和密码后,Acegi会通过预先...
用户提交的身份验证信息会经过认证Provider处理,一旦认证成功,Acegi会在SecurityContextHolder中设置一个SecurityContext对象,存储用户信息。 3. **授权机制**: 授权涉及决定用户是否有权访问特定资源。Acegi...
这个系统为Spring应用程序提供了全面的安全管理解决方案,包括身份验证、授权、会话管理以及安全事件处理等功能。虽然在Spring 3.0之后,Acegi 被Spring Security所取代,但其在当时对Spring社区的贡献是不可忽视的...
Acegi是Spring Security的前身,它是一个用于Java企业级应用的安全框架,提供了全面的身份验证、授权和会话管理功能。这个压缩包包含了Acegi的示例代码和一个学习资源,对于初学者来说是非常宝贵的资料。 首先,让...
AceGI,全称为Acegi Security,是Java领域中一个用于Spring框架的安全组件,它提供了全面的身份验证、授权和会话管理功能。这个框架在早期的Spring版本中非常流行,为开发者构建安全的Web应用程序提供了强大的支持。...
Acegi Security是Spring框架早期的一个安全模块,它提供了全面的基于Spring的应用程序的访问控制和身份验证功能。在本文中,我们将深入探讨如何使用Acegi Security来实现用户权限的控制。 Acegi Security的核心功能...
它提供了全面的身份验证、授权和访问控制功能,旨在确保企业级应用的安全性。Acegi通过AOP(面向切面编程)的概念,使得安全控制能够无缝地融入到应用程序的各个部分。 首先,让我们了解一下Acegi的基础概念: 1. ...
Acegi Security(现已被Spring Security替代)是一个基于Spring的应用程序安全框架,它提供了一整套工具和策略,用于实现身份验证、授权、会话管理以及访问控制等功能。这个框架允许开发者在不修改核心业务逻辑的...
首先,Acegi提供了身份验证和授权服务,确保只有合法用户能够访问应用程序的特定部分。在初体验部分,博主可能会介绍如何设置Acegi以保护一个简单的Spring应用,包括配置Spring XML文件、定义安全拦截器(filter)...
AceGI安全策略与CAS(Central Authentication Service)整合是企业级应用中常见的安全解决方案,它能够为Web应用程序提供统一的身份验证和授权服务。本文档旨在详细阐述这一整合过程,包括配置步骤、所需资源以及...
1. **身份验证**:在Acegi中,身份验证通常通过`AuthenticationProvider`实现,它可以是基于数据库、LDAP或者其他任何可以验证用户凭证的服务。`UsernamePasswordAuthenticationToken`是常用的认证令牌,包含用户名...
Acegi(现在已被Spring Security替代)在Spring应用程序中提供了身份验证、授权和会话管理等功能。 在Spring Acegi的例子中,我们首先需要了解的是基础概念: 1. **身份验证(Authentication)**:这是验证用户...
2. **HTTP摘要认证**:同样基于IETF RFC标准,提供更安全的身份验证方式。 3. **HTTP X.509客户端证书交换**:适用于需要更高级别安全性的场景。 4. **轻量级目录访问协议(LDAP)**:跨平台的认证方法,尤其适用于...
Acegi 安全框架是 Spring 框架的一个扩展,用于提供高级的身份验证和授权功能。在"使用 Acegi 保护 Java 应用程序:续二"这篇博文中,作者可能详细介绍了如何集成 Acegi 安全框架到 Java 应用程序中,以及如何配置和...
1. **定义用户身份验证机制**:在系统中,每个用户都有自己的身份,Acegi允许我们自定义身份验证过程。 2. **设置权限控制策略**:根据用户的登录状态及所扮演的角色,对不同的资源进行访问控制。 3. **配置会话管理...
Acegi是Spring Security的前身,是一个非常重要的Java安全框架,主要用于企业级应用的安全控制,如身份验证、授权等。 在Java Web开发中,安全性是至关重要的组成部分,而Acegi(现已被Spring Security所取代)提供...
3. **数据库验证**:Acegi Security支持基于数据库的身份验证。它可以与数据库中的用户账户信息进行交互,验证用户的用户名和密码。这涉及到数据库查询,以及如何将这些查询与Acegi的认证过程整合。 4. **加密**:...
Acegi Security 1.0.7是该组件的一个稳定版本,其核心功能包括身份验证、授权、会话管理以及一系列安全相关的服务。以下将详细阐述这些关键领域的实现和使用方法。 一、身份验证 Acegi Security的身份验证机制允许...
认证管理器是Acegi中负责用户身份验证的核心组件。它的主要任务是验证用户提供的主体(通常是用户名)和凭证(通常是密码)。认证管理器可以通过多种方式实现,如基于数据库或LDAP的身份验证。只有当用户的凭证被...