资源管理系统-Spring Security核心原理及实战
一、Spring Security 简介
Spring Security是一个功能强大且高度可定制的身份验证和访问控制框架。它是一套保护基于spring开发的应用程序的事实标准。Spring Security是一个重点为Java应用程序提供身份验证和授权的框架。与所有Spring项目一样,Spring Security的真正强大之处在于它可以很容易地扩展以满足定制需求。
二、Spring Security 核心功能
- 身份认证-用户登录;
- 访问授权-权限控制;
- 攻击防护-防止伪造身份;
三、Spring Security 基本原理
Spring Security核心就是一组过滤器链,每个过滤器实现一个独立功能,用户请求通过滤器链进行登录、授权、权限校验等操作,最终执行目标服务。
用户登录流程。用户登录过滤器用来拦截并处理用户登录请求,登录成功后使用SecurityContextHolder存储用户登录信息。例如,登录验证过滤器BasicAuthenticationFilter。当一个HTTP请求中包含一个名字为Authorization的头信息,并且其值格式是Basic xxx,BasicAuthenticationFilter会认为这是一个BASIC authorization头部,其中xxx部分应该是一个base64编码的{username}:{password}字符串。比如用户名/密码分别为 admin/secret, 则对应的该头部是 : Basic YWRtaW46c2VjcmV0,该过滤器会从 HTTP BASIC authorization头部解析出相应的用户名和密码然后调用AuthenticationManager进行认证,成功的话会把认证了的结果写入到SecurityContextHolder中SecurityContext的属性authentication上面,同时还会做其他一些处理,比如Remember Me相关处理等等。在返回登录结果前,SecurityContextPersistenceFilter过滤器会调用HttpSessionSecurityContextRepository将登录成功的用户登录信息放在服务器SESSION中,完成登录流程请求。Spring Security过滤器不止这一个身份认证过滤器,还有UsernamePasswordAuthenticationFilter用来处理表单登陆请求,只需要一点简单的配置就可以实现表单用户登录认证。当然,Spring Security有很强的的扩展性,开发者可以自定义过滤器加入到过滤器链中,实现自定义功能。
API访问流程。首先通过SecurityContextPersistenceFilter过滤器,该过滤器会从session中加载SecurityContext,SecurityContext包含了登录流程中保存的用户登录信息。经过一系列的过滤器后,走到FilterSecurityInterceptor过滤器,这个过滤器就比较关键了,他会使用SecurityContextHolder获取SecurityContext,SecurityContext为空则表示用户未登录,抛出AuthenticationCredentialsNotFoundException异常,不为空则使用AuthenticationManager做登录认证(用户是否已登录),登录认证通过后,使用AccessDecisionManager的decide方法做授权验证(用户是否有权限),验证完成后方可调用后端服务。注意,认证的任一环节不通过,则会抛出对应异常,异常由ExceptionTranslationFilter过滤器拦截做统一处理。
四、Spring Security 实战
首先,从官网上下载一个demo,下载地址:https://docs.spring.io/spring-security/site/docs/5.2.5.BUILD-SNAPSHOT/reference/htmlsingle/#preface,解压后,是一个名称为hello-security的java工程,使用IDEA打开。项目结构非常简单,一个启动类HelloSecurityApplication和一个配置文件application.properties。
MAVEN依赖主要有2个,SpringWebMVC和SpringSecurity相关依赖:
为了方便测试,我们在HelloSecurityApplication启动类中增加一个Hello接口:
一起准备就绪,启动测试一下,监听的端口为8080,然后我们请求地址为http://localhost:8080/hello,在浏览器里输入地址回车,结果并没有出现我们想的那样,而是跳转到了一个登录页面:
输入用户名user和启动时在控制台生成的一串密码,回车,神奇的事情发生了,我们的请求得到了响应。
我们来梳理一下刚才的访问流程:用户请求后台接口,层层过关,到达过滤器链的最低端FilterSecurityInterceptor,因为未登录,FilterSecurityInterceptor抛出异常被ExceptionTranslationFilter拦截,缓存请求地址信息后然后跳转到登录页面。输入用户信息后回车,用户登录请求被UsernamePasswordAuthenticationFilter拦截,验证身份信息后登录成功,从缓存中取出访问页面,将请求重定向到原请求地址,然后经过过滤器连最终到达后台API。
五、资源管理系统演示
项目演示地址:http://175.24.75.121/#/login
用户名:visitor
密码:visitor
六、GITHUB
前端工程:https://github.com/STIll-clx/rms-admin-web
后端工程:https://github.com/STIll-clx/rms