转载地址:http://www.blogjava.net/youxia/archive/2008/12/07/244883.html

在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_前缀当然没有关系,如果是像白衣这样是用三层关系,最好还是把这个前缀改一改,以免混淆。

Spring Side3的安全框架相关推荐

  1. 蚂蚁金服开源增强版 Spring Boot 的研发框架!

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 来源:gitee.com/sofastack/sofa-b ...

  2. 蚂蚁金服开源增强版Spring Boot 的研发框架!

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! SOFABoot 是蚂蚁金服开源的基于 Spring Bo ...

  3. 【struts2+spring+hibernate】ssh框架整合开发

    SSH框架整合 1 Struts2+Spring+Hibernate导包 Struts2导入jar包: * struts2/apps/struts2-blank.war/WEB-INF/lib/*.j ...

  4. 【spring boot】8.spring boot的日志框架logback使用

    在继续上一篇的Debug调试之后,把spring boot的日志框架使用情况逐步蚕食. 参考:http://tengj.top/2017/04/05/springbo 开篇之前,贴上完整applica ...

  5. Spring boot (6)---SpringMVC框架和spring Boot的区别

    SpringMVC框架和spring Boot的区别 1.我们知道Spring是一个一站式框架功能十分强大,就像一个家族,有众多衍生产品例如 boot.security.jpa等等.但他们的基础都是S ...

  6. Spring+SpringMVC+MyBatis+Maven框架整合

    本文记录了Spring+SpringMVC+MyBatis+Maven框架整合的记录,主要记录以下几点  一.Maven需要引入的jar包  二.Spring与SpringMVC的配置分离  三.Sp ...

  7. 前后端分离的用户验证原理及Spring Boot + JWT的框架搭建(附完整的框架代码)之二

    本篇承接上一篇,关于Session以及JWT Token参考: 前后端分离的用户验证原理及Spring Boot + JWT的框架搭建(附完整的框架代码)之一 框架整体描述 框架使用Spring Bo ...

  8. mybatis和spring jdbc持久层框架事务支持分析

    mybatis和spring jdbc持久层框架事务支持分析 ​ 持久层框架中的事务支持指的是持久层框架如何支持数据库事务,我们先梳理出原生数据库事务操作的主线脉络,它是通过java.sql 包下的C ...

  9. SSM框架实现用户查询、注册、登录——IDEA整合Spring、Spring MVC、Mybatis 框架

    目录 零.前言 一.说明 1.整合说明 2.最终目标 3.数据库准备 二.搭建整合环境 1.创建 maven 工程 2.导入依赖坐标 3.创建java和resources文件夹 4.创建类和接口文件 ...

  10. Spring batch批量处理框架最佳实践

    spring batch精选,一文吃透spring batch批量处理框架 前言碎语 批处理是企业级业务系统不可或缺的一部分,spring batch是一个轻量级的综合性批处理框架,可用于开发企业信息 ...

最新文章

  1. SQL Servr 2008空间数据应用系列六:基于SQLCRL的空间数据可编程性
  2. 自动调整速率的Actor设计模式
  3. 《Linux内核设计的艺术:图解Linux操作系统架构设计与实现原理》——2.15 本章小结...
  4. SAP 货物移动 BAPI 的简单使用 BAPI_GOODSMVT_CREATE
  5. 以太坊智能合约安全入门了解一下(下)
  6. github访问很慢解决方案
  7. Tomcat - Springboot启动的时候初始化的线程池默认配置
  8. c语言合法自定义标识符_c语言合法标识符的要求是什么
  9. H5+springboot(集成ffmpeg)实现前端视频录制以及webm格式转mp4
  10. 湖南省界矢量图_全国省、县界线shp格式矢量图(精确到县区域)
  11. d3 企业图谱 仿天眼查 企查查
  12. 免费|PDF文档翻译
  13. SqlServer存储过程中循环的使用
  14. 常见的Nginx 502 Bad Gateway解决办法
  15. sqlyog导入数据的两种方式
  16. js 时分秒比较大小
  17. Windows 那些坑
  18. 统计学习方法|隐马尔可夫模型
  19. 《计算机组成与系统结构(第二版) 裘雪红 李伯成 西安电子科技大学出版社》课后习题答案(带解析)(七)
  20. 百城优选广西馆怎么样?(个人)

热门文章

  1. STM32基于标准库函数和HAL库编程差异
  2. 巨头企业在区块链领域有哪些布局?
  3. Java:实现用拉普拉斯/余子式求nxn矩阵行列式算法(附完整源码)
  4. 观察者模式(Observer模式)详解——小马同学@Tian
  5. springboot项目中添加定时任务
  6. 全民一起VBA实战篇 专题4 第七回 递归不怕检索难,万缕千层只等闲
  7. codeforces1549 C. Web of Lies
  8. 【OpenJudge】寻找山顶
  9. Linux之Centos7安装配置中文输入法
  10. 免费delphi组件和工具收集