电商平台安全框架构建的分析
我的工程实践题目是关于电商功能平台构建的,每个构建完善的电商平台都会有安全框架来保证用户的信息安全,几乎所有的Web系统都需要登录、权限管理、角色管理等功能,而且这些功能往往具有较大的普适性,与系统具体的业务关联性较小。因此,这些功能完全可以被封装成一个可配置、可插拔的框架,当开发一个新系统的时候直接将其引入、并作简单配置即可,无需再从头开发,极大节约了人力成本、时间成本。我寻找到了一套安全框架,这套框架与Spring Boot深度融合,本文将从安全框架的设计与实现两个角度来分析这套框架。(项目完整源代码https://github.com/bz51/SpringBoot-Dubbo-Docker-Jenkins)
一、开发目标
在所有事情开始之前,我们首先要搞清楚,我们究竟要实现哪些功能?
1、用户登录 所有系统都需要登录功能,这毫无疑问,也不必多说。
2、角色管理 每个用户都有且仅有一种角色,比如:系统管理员、普通用户、企业用户等等。管理员可以添加、删除、查询、修改角色信息。
3、权限管理 每种角色可以拥有不同的权限,管理员可以创建、修改、查询、删除权限,也可以为某一种角色添加、删除权限。
4、权限检测 用户调用每一个接口,都需要校验该用户是否具备调用该接口的权限。
二、安全框架的实现
1、注解的实现
本套安全框架一共定义了四个注解:
@AuthScan 该注解用来告诉安全框架,本项目中所有Controller类所在的包,从而能够帮助安全框架快速找到Controller类,避免了所有类的扫描。它有且仅有一个参数,代码实现如下:
注解顾名思义,它是用来在代码中进行标注,它本身不承载任何逻辑
@Retention
它解释说明了这个注解的的存活时间。它的取值如下:
- RetentionPolicy.SOURCE 注解只在源码阶段保留,在编译器进行编译时它将被丢弃忽视。
- RetentionPolicy.CLASS 注解只被保留到编译进行的时候,它并不会被加载到 JVM 中。
- RetentionPolicy.RUNTIME 注解可以保留到程序运行的时候,它会被加载进入到 JVM 中,所以在程序运行时可以获取到它们。
- @Documented
顾名思义,这个元注解肯定是和文档有关。它的作用是能够将注解中的元素包含到 Javadoc 中去。 - @Target
当一个注解被 @Target 注解时,这个注解就被限定了运用的场景。
- ElementType.ANNOTATION_TYPE:可以给一个注解进行注解
- ElementType.CONSTRUCTOR:可以给构造方法进行注解
- ElementType.FIELD:可以给属性进行注解
- ElementType.LOCAL_VARIABLE:可以给局部变量进行注解
- ElementType.METHOD:可以给方法进行注解
- ElementType.PACKAGE:可以给一个包进行注解
- ElementType.PARAMETER:可以给一个方法内的参数进行注解
- ElementType.TYPE:可以给一个类型进行注解,比如类、接口、枚举。
@login这个注解用于标识指定接口是否需要登录后才能访问,它有一个默认的boolean类型的值,用于表示是否需要登录,其代码如下:
@Role该注解用于指定允许访问当前接口的角色,其代码如下:
@Permission该注解用于指定允许访问当前接口的权限,其代码如下:
2、权限信息初始化过程
1、在接口上声明权限信息:当完成这些注解的定义后,接下来就需要使用他们,如下面代码所示:
2、初始化权限信息
当系统初始化的时候,需要加载接口上的这些权限信息,存储在Redis中。在系统运行期间,当有用户请求接口的时候,系统会根据接口的权限信息判断用户是否有访问接口的权限。权限信息初始化过程的代码如下:
3、用户鉴权
当用户请求所有接口前,系统都应该拦截这些请求,只有在权限校验通过的情况下才运行调用接口,否则直接拒绝请求。
基于上述需求,我们需要给Controller中所有方法执行前增加切面,并将用于权限校验的代码织入到该切面中,从而在方法执行前完成权限校验。下面就详细介绍在SpringBoot中AOP的使用。
- 首先,我们需要在项目的pom中引入AOP的依赖:
创建切面类:
- 在类上必须添加
@Aspect
注解,用于标识当前类是一个AOP切面类 - 该类也必须添加
@Component
注解,让Spring初始化完成后创建本类的对象,并加入IoC容器中 - 然后需要使用
@Pointcut
注解定义切点;切点描述了哪些类中的哪些方法需要织入权限校验代码。我们这里将所有Controller类中的所有方法作为切点。 - 当完成切点的定义后,我们需要使用
@Before
注解声明切面织入的时机;由于我们需要在方法执行前拦截所有的请求,因此使用@Before
注解。 - 当完成上述设置之后,所有Controller类中的函数在被调用前,都会执行权限校验代码。权限校验的详细过程在
authentication()
方法中完成。
关于这套源代码还有很多地方可以分析,在这里只是挑了一部分大概讨论一下就不一一写出来了,有兴趣可以自己下载看看。