SpringSecurity原理剖析与权限系统设计

Spring Secutity和Apache Shiro是Java领域的两大主流开源安全框架,也是权限系统设计的主要技术选型。本文主要介绍Spring Secutity的实现原理,并基于Spring Secutity设计基于RBAC的权限系统

一、技术选型

为何把Spring Secutity作为权限系统的技术选型,主要考虑了以下几个方面:

数据鉴权的能力:Spring Secutity支持数据鉴权,即细粒度权限控制。

Spring生态基础:Spring Secutity可以和Spring生态无缝集成。

多样认证能力:Spring Secutity支持多样认证方式,如预认证方式可以与第三方认证系统集成。

Spring Security Apache Shiro
认证   支持多种认证方式(如密码、匿名、预认证   简单登录认证  
鉴权   功能鉴权、数据鉴权   功能鉴权  
多源适配   Mem、JDBC、DAO、LDAP、
OpenID、OAuth等
  LDAP、JDBC、Kerberos、
ActiveDirectory等
 
加密   支持多种加密方式   简单加密方式  
运行环境   依赖Spring   可独立运行  
开放性   开源、Spring生态基础   开源  
复杂度   复杂、较重   简单、灵活  
二、核心架构

权限系统一般包含两大核心模块:认证(Authentication)和鉴权(Authorization)。

认证:认证模块负责验证用户身份的合法性,生成认证令牌,并保存到服务端会话中(如TLS)。

鉴权:鉴权模块负责从服务端会话内获取用户身份信息,与访问的资源进行权限比对。

官方给出的Spring Security的核心架构图如下:

SpringSecurity原理剖析与权限系统设计

核心架构解读:

AuthenticationManager:负责认证管理,解析用户登录信息(封装在Authentication),读取用户、角色、权限信息进行认证,认证结果被回填到Authentication,保存在SecurityContext。

AccessDecisionManager:负责鉴权投票表决,汇总投票器的结果,实现一票通过(默认)、多票通过、一票否决策略。

SecurityInterceptor:负责权限拦截,包括Web URL拦截和方法调用拦截。通过ConfigAttributes获取资源的描述信息,借助于AccessDecisionManager进行鉴权拦截。

SecurityContext:安全上下文,保存认证结果。提供了全局上下文、线程继承上下文、线程独立上下文(默认)三种策略。

Authentication:认证信息,保存用户的身份标示、权限列表、证书、认证通过标记等信息。

SecuredResource:被安全管控的资源,如Web URL、用户、角色、自定义领域对象等。

ConfigAttributes:资源属性配置,描述安全管控资源的信息,为SecurityInterceptor提供拦截逻辑的输入。

三、设计原理

通过对源码的分析,我把Spring Security的核心领域模型设计整理如下:

SpringSecurity原理剖析与权限系统设计

全局抽象模型解读:

配置:AuthenticationConfiguration负责认证系统的全局配置,GlobalMethodSecurityConfiguration负责方法调用拦截的全局配置。

构建:AuthenticationConfiguration通过AuthenticationManagerBuilder构建认证管理器AuthenticationManager,GlobalMethodSecurityConfiguration会自动初始化AbstractSecurityInterceptor进行方法调用拦截。

Web拦截:HttpSecurity对Web进行安全配置,内置了大量GenericFilterBean过滤器对URL进行拦截。负责认证的过滤器会通过AuthenticationManager进行认证,并将认证结果保存到SecurityContext。

方法拦截:Spring通过AOP技术(cglib/aspectj)对标记为@PreAuthorize、@PreFilter、@PostAuthorize、@PostFilter等注解的方法进行拦截,通过AbstractSecurityInterceptor调用AuthenticationManager进行身份认证(如果必要的话)。

认证:认证管理器AuthenticationManager内置了多种认证器AuthenticationProvider,只要其中一个认证通过,认证便成功。不同的AuthenticationProvider获取各自需要的信息(HTTP请求、数据库查询、远程服务等)进行认证,认证结果全部封装在Authentication。需要加载用户、角色、权限信息的认证器(如密码认证、预认证等)需要对接UserDetailsManager接口实现用户CRUD功能。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyywwy.html