Spring Security(maven项目) 3.0.2.3版本
前言
通过实践而发现真理,又通过实践而证实真理和发展真理。从感性认识而能动地发展到理性认识,又从理性认识而能动地指导革命实践,改造主观世界和客观世界。实践、认识、再实践、再认识,这种形式,循环往复以至无穷,而实践和认识之每一循环的内容,都比较地进到了高一级的程度
既然路走错了,来的路也忘了,那么,经典回放——从新开始SpringSecurity
正片
第一篇:认识SpringSecurity
经典三问:
SpringSecurity是什么?
为什么用SpringSecurity?
怎么使用SpringSecurity?
SpringSecurity是什么?
为什么用SpringSecurity?
怎么使用SpringSecurity?
总结:
A:SpringSecurity是什么?
Q:Spring Security是一个框架,提供 认证(authentication)、授权(authorization) 和 保护,以抵御常见的攻击。它对保护命令式和响应式应用程序有一流的支持,是保护基于Spring的应用程序的事实标准。
A:为什么用SpringSecurity?
Q:Spring Security是一个强大且易于使用的框架,可以帮助开发人员提高应用程序的安全性和可靠性
A:怎么使用
Q:继续看下去
第二篇:初步体验SpringSecurity
获得Hello Spring Security
点击链接进行下载——点击下载一个 由 Spring Initializr 准备的 最小的 Spring Boot + Spring Security 应用程序
下载解压完后,打开后显示的文件结构:
启动Hello Spring Security
理论结果:如上图
实践结果:如下图
结论:理论结果等于实践结果
体验Hello Spring Security在项目的作用
第一个体验:复制URL进浏览器
理论结果:返回默认登录页面
实践结果:返回默认登录页面
结论:理论符合实践
你带有凭证请求一个端点
理论结果如:上图
实践结果如:下图
结论:理论符合实践
总结:
启动Spring Security时会生成一个默认用户,使用用户进行登录认证,验证SpringSecurity是什么中的认证作用
第三篇:进一步认识SpringSecurity
理论认识:如下
实践结果:
任何端点需要认证用户符合
提供内容协商;对于web请求,重定向到登录页面;对于服务请求,返回 401 Unauthorized
。
在启动时用生成的密码 注册一个默认用户(密码被记录到控制台;在前面的例子中,密码是 8e557245-73e2-4286-969a-ff57fe326336
)
提供基于表单的 登录 和 注销 流程。
发布 认证成功和失败的事件
总结:
其中只有六条可在当前阶段实践验证
第一条:任何端点需要认证用户符合
第二条:提供内容协商;对于web请求,重定向到登录页面;对于服务请求,返回 401 Unauthorized
第三条:
在启动时用生成的密码 注册一个默认用户(密码被记录到控制台;在前面的例子中,密码是 8e557245-73e2-4286-969a-ff57fe326336
)
第四条:
在启动时用生成的密码 注册一个默认用户(密码被记录到控制台;在前面的例子中,密码是 8e557245-73e2-4286-969a-ff57fe326336
)
第五条:提供基于表单的 登录 和 注销 流程。
第六条: 发布 认证成功和失败的事件
第四篇:SpringSecurity的架构图(上)
有图先看图,因为图好理解,更因为图是文字的浓缩,就像在java入门中所说,现实是文字的环境,环境就像一幅画一样,我们只不过是用文字去复刻出一副和现实一样的画而已
翻译一下,跟金字塔一样
认识上下文持有者
前端发送请求,进入后端,后端处理请求,他们之间的SpringSecurity叫上下文承担者
简单来说,上下文承担者需要在上文和下文之间,之间的代码称之为承担者
SecurityContextHolder
试试这段代码
测试代码
@SpringBootApplication
public class HelloSecurityApplication {
public static void main(String[] args) {
SecurityContext context = SecurityContextHolder.createEmptyContext();
Authentication authentication =
new TestingAuthenticationToken("username", "password", "ROLE_USER");
context.setAuthentication(authentication);
SecurityContextHolder.setContext(context);
SpringApplication.run(HelloSecurityApplication.class, args);
System.out.println("测试内容在下");
System.out.println(context); //打印context
}
}
测试结果如下:
SecurityContextImpl [Authentication=TestingAuthenticationToken [Principal=username, Credentials=[PROTECTED], Authenticated=true, Details=null, Granted Authorities=[ROLE_USER]]]
读源码前,先看这张图片
结合这个,你能更容易去理解官方代码
一切基于SecurityContextHolder,起点
调用SecurityContextHolder类的createEmptyContext方法
翻译一下,Security上下文持有者创建了一个空的Security内容
面向对象编程的经典案例+1——谁做了什么
内容包括了什么?Authentication,其中Authentication里包含了三类
像不像金字塔,SecurityContextHolder是最底层,可以来一个 公式,底层等于n-1的顶层,将底层等于1时,顶层将不复存在,没有底层作为载体,金字塔无法纯在
然后new了一个TestingAuthenticationToken,测试身份验证令牌
可是官方文档里没有TestingAuthenticationToken,但是官方也说了这么一句话——Spring Security 并不关心 SecurityContextHolder
是如何被填充的,那我们就先单认为TestingAuthenticationToken当成一个简单的测试类
context.setAuthentication(authentication);
SecurityContextHolder.setContext(context);
这两句结合上面的金字塔理论(我暂时命名为金字塔理论),顶层是基于底层而构建的,需要一层一层建造
看,官方都在推荐金字塔构建,而不是一次性构建完
大胆实践!
通过修改testAuthenticationToken测试认证令牌,看会有什么效果
看到源码
重点在于形参:Object principal, Object credentials, String... authorities
对象,对象,字符串...
在阅读源码时,我突发奇想
TestingAuthenticationToken是类名为什么会是Authentication类里的?
来源于继承
总结:
认证框架来源于SecurityContextHolder,结合之前的内容,我们可以知道,官方提供了一整条的authentication认证代码,并且设置为了context
为了避免多线程竞争,采用金字塔结构,构建SecurityContextHolder代码
使用TestingAuthenticationToken是因为足够简单,生产更多使用UsernamePasswordAuthenticationToken(userDetails, password, authorities)
。