《Spring技术内幕:深入解析Spring架构与设计原理》笔记之八(安全框架ACEGI的设计与实现)

1.Spring ACEGI安全框架概述

1.1概述

ACEGI能够为基于Spring构建的应用项目提供全面的安全服务,处理应用需要的各种典型的安全需求,如用户的身份验证和用户授权等。

1.2设计原理与基本实现过程

ACEGI安全应用模块与其他Spring的上层应用模块一样,都建立在IOC容器和AOP的基础上,也可以把ACEGI看成是一个特殊的Spring应用。作为Spring应用,ACEGI提供的安全服务可以通过IOC容器的配置来使用,这部分的配置过程和其他Spring的其他的应用类似。比如,对于不同的用户登录请求,ACEGI提供了不同的拦截器供用户使用,其中比较熟悉的是基于Web页面表单的登录请求拦截,这是需要配置的一个部分,具体地说,是需要配置不同的AuthenticationProcessingFilter来满足用户的验证需求。

Spring ACEGI设计时序

《Spring技术内幕:深入解析Spring架构与设计原理》笔记之八(安全框架ACEGI的设计与实现)

1.3ACEGI的Bean配置

ACEGI的Bean配置

《Spring技术内幕:深入解析Spring架构与设计原理》笔记之八(安全框架ACEGI的设计与实现)

2.配置Spring ACEGI

再具体的authenticationProvider的Bean配置中,还需要定义一个userDetailService属性,该属性是一个DAO对象,通过它可以完成从数据库中读取用户信息的工作。这个数据验证过程与使用其他的数据验证提供器的验证过程是大致相同的,不同之处只在于,在服务器端,应用可以使用不同的身份数据的存储方式,因而会导致使用不同的数据读取方式,从而可以从不同的数据源得到用户数据。

HSQLDB:一个开源的数据库引擎,由于是Java的实现,在Java应用开发中使用起来非常方便。非常适用于Java数据库应用开发、测试。

3.ACEGI的Web过滤器实现

ACEGI配置中,是通过AuthenticationProcessingFilter的过滤功能来启动Web页面的用户验证实现的。在AuthenticationProcessingFilter中,其验证过程是在它的attemptAuthentication方法中实现。在attemptAuthentication方法中的实现中,首先会从HTTP请求中取得用户名和密码,在得到HTTP请求中的用户验证信息以后,会生成一个Token对象来封装这些信息,最后把这个Token对象交给配置的authenticationManager验证器来完成具体验证工作,从而完成web应用需要的用户验证。

从通过HTTP输入得到验证信息开始,到开始启动authenticationManager验证器,直到用户验证的最终完成,这时开始进入到与web页面处理无关的工作,这些工作是由验证器来完成的。

4.ACEGI验证器的实现

4.1AuthenticationManager的authenticate

ACEGI框架中,完成验证工作的主要类是AuthenticationManager,我们称之为验证器。在这个验证器的实现中,完成验证调用入口是authenticate方法。

4.2DaoAuthenticationProvider的实现

在DaoAuthenticationProvider的基类AbstractUserDetailsAuthenticationProvider实现中,定义了验证的处理模板,同时,在基类AbstractUserDetailsAuthenticationProvider中,实现了接口AuthenticationProvider、MessageSourceAware以及InitializationBean,除了DaoAuthenticationProvider可以从数据库中获取用户验证信息之外,还提供其他子类可以从其他的途径获得用户验证信息,比如要从LDAP获得用户验证信息,可以使用LdapDaoAuthenticationProvider来获取用户验证信息。

验证数据提供器的设计

《Spring技术内幕:深入解析Spring架构与设计原理》笔记之八(安全框架ACEGI的设计与实现)

4.3读取数据库用户信息

ACEGI实现中,获取服务器端用户信息的工作是由具体的数据提供器(Provider)来完成的。

4.4完成用户信息的对比验证

由于存储在数据库中的用户密码是经过MD5加密的,因此在实现密码对比之前,需要使用配置的passwordEncoder对象来对用户输入的密码进行MD5加密。在得到加密后的输入密码以后,才能将这个加密密码与在服务器数据库中设置的密码进行比较。根据比较结果,两者相同表示通过验证;否则将会抛出异常,表明验证失败。

5.ACEGI授权器的实现

5.1与web环境的接口FilterSecurityInterceptor

FilterSecurityInterceptor拦截器中,与前面看到其他Servlet拦截器一样,也是通过doFilter方法来对HTTP请求进行拦截和处理的。

5.2授权器的实现

为用户授权是由AccessDecisionManager授权器来完成的,授权的过程在授权器的decide方法中实现。

授权器的类继承关系设计

《Spring技术内幕:深入解析Spring架构与设计原理》笔记之八(安全框架ACEGI的设计与实现)

5.3投票器的实现

ACEGI中,对应现实世界的投票决策过程设计了对应的投票器类继承关系

投票器的类继承关系设计

《Spring技术内幕:深入解析Spring架构与设计原理》笔记之八(安全框架ACEGI的设计与实现)

在投票前,首先设置一个变量来记录投票结果,这个投票结果的初始值被设置为ACCESS_ABSTAIN;然后投票器会读入对URL资源配置的安全需求,根据这些安全需求逐条进行判断。如果资源配置的授权角色与当前请求用户的角色配置相匹配,安全需求得到满足,那么将会投票表示同意;反之,投票表示反对。在这个判断完成以后,最后会返回投票结果,完成投票器的判断工作。