在SpringSide 3的官方文档中,说安全框架使用的是Spring Security 2.0。乍一看,吓了我一跳,以为Acegi这么快就被淘汰了呢。上搜索引擎一搜,发现原来Spring Security 2.0就是Acegi 2.0。悬着的心放下来了。虽然SpringSide 3中关于Acegi的配置文件看起来很不熟悉,但是读了Acegi 2.0的官方文档后,一切都释然了。
先来谈一谈Acegi的基础知识,Acegi的架构比较复杂,但是我希望我下面的只言片语能够把它说清楚。大家都知道,如果要对Web资源进行保护,最好的办法莫过于Filter,要想对方法调用进行保护,最好的办法莫过于AOP。Acegi对Web资源的保护,就是靠Filter实现的。如下图:
一般来说,我们的Filter都是配置在web.xml中,但是Acegi不一样,它在web.xml中配置的只是一个代理,而真正起作用的Filter是作为Bean配置在Spring中的。web.xml中的代理依次调用这些Bean,就实现了对Web资源的保护,同时这些Filter作为Bean被Spring管理,所以实现AOP也很简单,真的是一举两得啊。
Acegi中提供的Filter不少,有十多个,一个一个学起来比较复杂。但是对于我们Web开发者来说,常用的就那么几个,如下图中的被红圈圈标记出来的:
从上到下,它们实现的功能依次是1、制定必须为https连接;2、从Session中提取用户的认证信息;3、退出登录;4、登录;5、记住用户;6、所有的应用必须配置这个Filter。
一般来说,我们写Web应用只需要熟悉这几个Filter就可以了,如果不需要https连接,连第一个也不用熟悉。但是有人肯定会想,这些Filter怎么和我的数据库联系起来呢?不用着急,这些Filter并不直接处理用户的认证,也不直接处理用户的授权,而是把它们交给了认证管理器和决策管理器。如下图:
对于这两种管理器,那也是不需要我们写代码的,Acegi也提供了现成的类。那么大家又奇怪了:又是现成的,那怎么和我的数据库关联起来呢?别着急,其实这两个管理器自己也不做事,认证管理器把任务交给了Provider,而决策管理器则把任务交给了Voter,如下图:
现在我要告诉你们,这里的Provider和Voter也是不需要我们写代码的。不要崩溃,快到目标了。Acegi提供了多个Provider的实现类,如果我们想用数据库来储存用户的认证数据,那么我们就选择DaoAuthenticationProvider。对于Voter,我们一般选择RoleVoter就够用了,它会根据我们配置文件中的设置来决定是否允许某一个用户访问制定的Web资源。
而DaoAuthenticationProvider也是不直接操作数据库的,它把任务委托给了UserDetailService,如下图:
而我们要做的,就是实现这个UserDetailService。图画得不好,大家不要见笑,但是说了这么多总算是引出了我们开发中的关键,那就是我们要实现自己的UserDetailService,它就是连接我们的数据库和Acegi的桥梁。UserDetailService的要求也很简单,只需要一个返回org.springframework.security.userdetails.User对象的loadUserByUsername(String userName)方法。因此,怎么设计数据库都可以,不管我们是用一个表还是两个表还是三个表,也不管我们是用户-授权,还是用户-角色-授权,还是用户-用户组-角色-授权,这些具体的东西Acegi统统不关心,它只关心返回的那个User对象,至于怎么从数据库中读取数据,那就是我们自己的事了。
反过来再看看上面的过程,我们发现,即使我们要做的只是实现自己的UserDetailService类,但是我们不得不在Spring中配置那一大堆的Bean,包括几个Filter,几个Manager,几个Provider和Voter,而这些配置往往都是重复的无谓的。好在Acegi 2.0也认识到了这个问题,所以,它设计了一个<http>标签,让Acegi的配置得到了简化。下面是SpringSide 3中的配置的截图,大家可以看看:
下图是官方文章中的传统Filter设置和<http>元素之间的对应关系:
下面的代码是SpringSide 3中实现UserDetailService的范例,在SpringSide 3的范例中,白衣使用了三个表User、Role、Authority。但是Acegi不关心你用了几个表,它只关心UserDetails对象。而决定用户能否访问指定Web资源的,是RoleVoter类,无需任何修改它可以工作得很好,唯一的缺点是它只认ROLE_前缀,所以搞得白衣的Authority看起来都象角色,不伦不类。
package personal.youxia.service.security;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.dao.DataAccessException;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.GrantedAuthorityImpl;
import org.springframework.security.userdetails.UserDetails;
import org.springframework.security.userdetails.UserDetailsService;
import org.springframework.security.userdetails.UsernameNotFoundException;
import personal.youxia.entity.user.Authority;
import personal.youxia.entity.user.Role;
import personal.youxia.entity.user.User;
import personal.youxia.service.user.UserManager;
/**
* 实现SpringSecurity的UserDetailsService接口,获取用户Detail信息.
*
* @author calvin
*/
public class UserDetailServiceImpl implements UserDetailsService {
private UserManager userManager;
public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException, DataAccessException {
User user = userManager.getUserByLoginName(userName);
if (user == null )
throw new UsernameNotFoundException(userName + " 不存在 " );
List < GrantedAuthority > authsList = new ArrayList < GrantedAuthority > ();
for (Role role : user.getRoles()) {
for (Authority authority : role.getAuths()) {
authsList.add( new GrantedAuthorityImpl(authority.getName()));
}
}
// 目前在MultiDatabaseExample的User类中没有enabled, accountNonExpired,credentialsNonExpired, accountNonLocked等属性
// 暂时全部设为true,在需要时才添加这些属性.
org.springframework.security.userdetails.User userdetail = new org.springframework.security.userdetails.User(
user.getLoginName(), user.getPassword(), true , true , true , true , authsList
.toArray( new GrantedAuthority[authsList.size()]));
return userdetail;
}
@Required
public void setUserManager(UserManager userManager) {
this .userManager = userManager;
}
}
最后再来说说这个命名的问题,我对Authentication和Authority这两个单词比较反感,两个原因,一是因为它们太生僻了,二是因为它们长得太像了,明明一个是认证,一个是授权,意思相差很远,外貌却如此相似,确实很烦人。如果让我来选择,我喜欢Privilege这个单词,在我刚使用MySQL的时候就跟它很熟了,所以在我的项目中,我可能会用Privilege来代替Authority。如果我们只使用User-Role两级关系,使用RoleVoter默认的ROLE_前缀当然没有关系,如果是像白衣这样是用三层关系,最好还是把这个前缀改一改,以免混淆。
分享到:
相关推荐
SpringSide安全框架是一个基于Spring Boot和Spring Security的实践示例,旨在帮助开发者更好地理解和应用安全控制在实际项目中。这个demo实例提供了丰富的功能,涵盖了身份验证、授权、密码加密、会话管理等多个方面...
通过集成Spring Security或Apache Shiro等安全框架,SpringSide可以实现细粒度的权限控制,确保系统在不同用户、不同场景下的安全性。 五、SpringSide的项目结构与实践 SpringSide项目通常采用模块化设计,包括...
在本次讨论中,我们将深入探讨springside3-core-3.3.4.jar这一核心组件,它是SpringSide 3项目的基石,包含了项目的核心功能和模块。 1. **SpringSide 3概述**: SpringSide 3 是由中国的Java社区开发的一个开源...
SpringSide3-core-3.3.4是SpringSide项目的一个重要版本,它是一个基于Java的轻量级开发框架,旨在简化Spring的使用,提高开发效率。这个压缩包包含了两个关键文件:springside3-core-3.3.4.jar和springside3-...
SpringSide3是一个基于Spring框架的开发工具,旨在简化Java企业级应用的开发流程。这个框架提供了项目生成器,使用Maven的archetype插件来创建符合特定规范的项目结构。SpringSide3.0使用Velocity语法的项目模板,...
Shiro Security框架部分则介绍了如何在SpringSide项目中进行安全控制。 在介绍了常规模块之后,文档还专门提供了一节关于加密技术的章节,包括消息摘要和加密方法,以及如何在SpringSide中使用Crypto组件。 ...
2. **安全框架集成**:集成了Spring Security,提供了用户认证、授权等功能,保障了应用的安全性。 3. **数据访问层**:支持多种ORM框架,如Hibernate和MyBatis,提供统一的DAO接口,降低了数据访问层的复杂性。 4...
springside是一款基于Spring框架的轻量级开发工具集,它为Java开发提供了简洁、高效的解决方案,尤其适合中大型项目的开发。尽管springside集合了多种复杂的技术,但这并不意味着初学者无法涉足。本资料将由浅入深,...
8. **安全控制**:Spring Security(前身Acegi Security)被集成到SpringSide 3.0中,提供了一套全面的安全管理方案,包括身份验证、授权、会话管理等。 9. **日志管理**:SpringSide 3.0 使用Log4j或Logback作为...
综上所述,《SpringSide 2.0中文使用说明》涵盖了Spring框架的集成、项目结构设计、构建工具、ORM解决方案、测试策略、RESTful服务、安全控制以及文档支持等多个关键知识点,为Java开发者提供了一套全面的实战指导。...
综上所述,SpringSide 4.0.0.RC3 是一个以 Spring Framework 为基础,集成了 Spring security 等关键组件的全栈企业级应用开发框架。它提供了便捷的初始化脚本、明确的项目结构、丰富的示例以及灵活的模块化设计,...
标题 "Springside" 暗示我们正在讨论一个与Spring框架相关的开源项目或工具。SpringSide是一个基于Spring Boot的轻量级...如果你是一名Java开发者,掌握SpringSide能够让你在Spring框架下的开发工作中更加得心应手。
3. **整合Apache Shiro**:Apache Shiro是一个强大的安全框架,用于身份验证、授权和会话管理。在SpringSide5中,Shiro被用来实现用户权限控制,提供安全的登录、授权功能,确保只有授权用户可以访问特定资源。 4. ...
"springside 架包"中的4.2.3.GA版本,代表着这是一个稳定且经过广泛测试的版本,为用户提供了安全可靠的开发环境。 1. **SpringSide的核心理念**: SpringSide致力于简化Spring的使用,通过提供清晰的代码示例、...
【标题】"springside-案例"所涉及的是SpringSide项目,这是一个开源的Java开发框架,旨在简化Spring框架的使用,提高开发效率。SpringSide是一个精心设计的、用于快速构建企业级应用的模板项目,它提供了清晰的代码...
springside-extension模块是针对Spring框架的扩展,包含了一些实用的工具类和配置,如日志管理、缓存支持、安全控制等。这些扩展使得开发者能够更便捷地实现常见的业务需求,降低了开发难度。 五、springside-...
SpringSide是基于Spring框架的一个轻量级、模块化、规范化的开发工具集,旨在提供一种快速、高效且易于维护的Java Web开发模式。在这个实例中,我们将深入探讨如何利用SpringSide进行实际项目开发,特别是其在构建...
6. **安全控制**:Springside提供了基于Spring Security的安全控制模块,可以快速实现用户认证与授权功能,增强了应用的安全性。 7. **日志管理**:集成了Logback作为日志系统,提供了灵活的日志级别控制和输出格式...
【Springside4 学习整理】 Springside4 是一个基于 JavaEE 平台的开源项目,它围绕 Spring ...同时,通过其提供的工具类,开发者可以更便捷地处理日常开发中的一些常见任务,如数据验证、对象映射和安全控制等。