随笔-54  评论-0  文章-2  trackbacks-0
 接着昨天的实现将拦截的url,权限信息,用户信息放到数据库中,并将spring-security集成到项目中

1. 实现资源信息存放到数据库中:

访问资源时, spring-security 能区分出访问该资源需要哪些权限
  1. 自定义ObjectDefinitionSource 接口的实现类, 将该类的实例装配给 FilterSecurityInterceptor 的 objectDefinitionSource 的属性. 即可实现自定义的资源获取.

  2. 通过继承 DefaultFilterInvocationDefinitionSource 类的方法定义ObjectDefinitionSource 接口的实现类有困难, 因为 DefaultFilterInvocationDefinitionSource中没有无参的构造器

   3.通过查看 spring-security 核心 jar 包的 META-IN 下 的 spring.handlers 找到 SecurityNamespaceHandler, 在该类中查看 registerBeanDefinitionParser(Elements.HTTP, new HttpSecurityBeanDefinitionParser()); 方法在 HttpSecurityBeanDefinitionParser 类中可以看到如何创建 DefaultFilterInvocationDefinitionSource 实例.

   4. 通过 FactoryBean 在 IOC 容器中注册  DefaultFilterInvocationDefinitionSource 实例   

   5. 实现ResourceDetailsService 接口    

2.关于MD5加密:

1.网上的关于MD5已经很多了,MD5算法对密码进行摘要加密,这是一种单项加密手段,无法通过加密后的结果反推回原来的密码明文。

为了使用MD5对密码加密,我们需要修改一下配置文件
<authentication-provider>
    <password-encoder hash="md5" >
    <jdbc-user-service data-source-ref="dataSource" >
< authentication-provider>  
上述代码中新增的黄色部分,将启用md5算法。

3.管理会话(HttpSession)
    多个用户不能使用同一个账号同时登陆系统。
添加监听器
在web.xml中添加一个监听器,这个监听器会在session创建和销毁的时候通知Spring Security。
这种监听session生命周期的监听器主要用来收集在线用户的信息,比如统计在线用户数之类的事。后登陆的将先登录的踢出系统默认情况下,后登陆的用户 会把先登录的用户踢出系统。

============================================================================================
                              集成spring-security框架

1. 集成 spring-security 框架

    1. 加入 spring-security 的两个 jar 包
    2. 在 web.xml 文件中加入加入 spring-security 框架的过滤器
    3. 新建 applicationContext-security.xml 配置文件,并且把 security 作为默认的命名空间, 并将其导入到 applicationContext.xml 中
    4. 设计领域模型:
       Authority -- 权限
       Resource -- 资源
       Role -- 角色
       Employee -- 添加 Set<Role> roleSet 属性

       Resource 和 Authority 为多对多的对应关系
       Authority 和 Role 为多对多的对应关系
       Role 和 Employee 为多对多的对应关系
需要 3 个关联表
    5.
       1. 修改当前系统的 login.jsp 页面, 改为 spring-security 的登录页面, 并且在 <http> 节点中进行配置.
注意: spring-security 在登录成功后, 利用 "重定向" 转到 form-login 节点对应的 default-target-url 属性对应的页面. 所以不能直接将其配置为 WEB-INF 目录下的任何页面
      2. 新建 UserDetailsService 接口的实现类, 以实现从数据库中获取用户信息(需要查询 Employee, Role, Authority, 参见 spring-security-2 的UserDetailsServiceImpl, 基于 Hibernate 实现),并把该类的 Bean 引用装配给 <authentication-provider> 节点的 user-service-ref 属性 
    6. 向 ems_resource_table, ems_authority_table, ems_resource_authority_table 数据表中添加数据
    7. 新建 ResourceDetailsService 接口的实现类, 实现从数据库中读取需要被保护的资源信息及其可以访问这些资源的权限信息
    8. 利用 FactoryBean 新建 DefaultFilterInvocationDefinitionSource 接口的 Bean, 并把  ResourceDetailsService 的 Bean 注入进来, 再把该 Bean 配置为 filterSecurityInterceptor 过滤器的 objectDefinitionSource 属性

2. 实现权限模块:
 1. 实现 Role 的增, 删, 改, 查

        角色的添加:

      页面 UI:
              a. 对字段的 jQuery validation 验证
              b. struts validator 验证 **
              c. Action的复杂验证: 角色名不能重复 **.
              d. 角色名的 ajax 验证, 角色名不能重复 **.
              e. 勾选权限时的级联选择. 例如: 勾选 "员工删除" 的同时必须勾选 "员工查询", 即不能让用户只有 "员工删除" 权限, 而没有 "员工查询" 权限.
              f. 使用到 Authority 的如下两个字段: relatedAuthorites(与当前权限关联的权限信息, 多个权限使用 "," 分隔), parentAuthority(当前权限的父权限)
subAuthorities(当前权限的子权限)            
       若验证都通过, 在 Action 中受理请求, 录入角色
   
注意:

       不能通过以下代码获取 parentAuthority 为 null 的 Authority 集合
       List list = authorityDao.findBy("parentAuthority", null);
       System.out.println(list.size());
而应该使用:

       List list = authorityDao.find("FROM Authority auth WHERE auth.parentAuthority IS null");
    为 #select 添加 change 相应事件, 当选取某个父权限时, 子权限显示


今天就此为止,明天继续!
posted on 2010-03-13 23:21 d66380022 阅读(1166) 评论(0)  编辑  收藏