整体概述
运行时环境
Spring Security 3.0 需要 Java 5.0 Runtime Environment 或更高版本.
核心组件
SecurityContextHolder,SecurityContext 和 Authentication Objects
最基本的对象是 SecurityContextHolder. 这是我们存储应用程序当前安全上下文的详细信息的地方, 其中包括当前使用该应用程序的主体的详细信息. 默认情况下, SecurityContextHolder 使用 ThreadLocal 来存储这些详细信息, 这意味着安全上下文始终可用于同一执行线程中的方法, 即使安全上下文未作为参数显式传递那些方法. 如果在处理当前委托人的请求之后小心地清除线程, 以这种方式使用 ThreadLocal 是非常安全的. 当然, Spring Security 会自动为您解决这个问题, 因此无需担心.
获取有关当前用户的信息
在 SecurityContextHolder 内, 我们存储了当前与应用程序交互的主体的详细信息. Spring Security 使用 Authentication 对象来表示此信息. 您通常不需要自己创建 Authentication 对象, 但用户查询 Authentication 对象是相当常见的. 您可以使用以下代码块 (从应用程序的任何位置) 获取当前经过身份验证的用户的名称
- Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
- if (principal instanceof UserDetails) {
- String username = ((UserDetails)principal).getUsername();
- } else {
- String username = principal.toString();
- }
- UserDetailsService
用来查询数据库, 加载用户信息的接口
UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
需要注意
UserDetailsService 经常有些混乱. 它纯粹是用户数据的 DAO, 除了将数据提供给框架内的其他组件之外, 不执行任何其他功能. 特别是, 它不会对用户进行身份验证, 这是由 AuthenticationManager 完成的. 在许多情况下, 如果您需要自定义身份验证过程, 直接实现 AuthenticationProvider 会更有意义.
GrantedAuthority
除了校长之外, Authentication 提供的另一个重要方法是 getAuthorities(). 此方法提供 GrantedAuthority 个对象的数组. 毫不奇怪, GrantedAuthority 是授予校长的权力. 这些权力通常是 "角色", 例如 ROLE_ADMINISTRATOR 或 ROLE_HR_SUPERVISOR. 稍后将为 web 授权, 方法授权和域对象授权配置这些角色. Spring Security 的其他部分能够解释这些权威, 并期望它们存在. GrantedAuthority 对象通常由 UserDetailsService 加载.
小结
回顾一下, 到目前为止我们看到的 Spring Security 的主要构建块是:
SecurityContextHolder, 提供 SecurityContext 的访问权限.
SecurityContext, 保存 Authentication 和可能的特定于请求的安全信息.
Authentication, 以特定于 Spring Security 的方式代表校长.
GrantedAuthority, 以反映授予主体的应用程序范围的权限.
UserDetails, 提供从应用程序的 DAO 或其他安全数据源构建 Authentication 对象所需的信息.
UserDetailsService, 在基于 String 的用户名 (或证书 ID 等) 中传递时创建 UserDetails.
认证 Authentication
在 Spring Security 内认证的流程.
获取用户名和密码并将其合并到 UsernamePasswordAuthenticationToken 的实例中(我们之前看到的 Authentication 接口的实例).
令牌被传递给 AuthenticationManager 的实例以进行验证.
AuthenticationManager 在成功验证后返回完全填充的 Authentication 实例.
通过调用 SecurityContextHolder.getContext().setAuthentication(...)建立安全上下文, 传入返回的身份验证对象.
例子:
代码:
https://github.com/victorsheng/gs-securing-web/blob/master/complete/src/test/java/helloworld/AuthenticationExample.java
结果
- Please enter your username:
- hi
- Please enter your password:
- hi1
- Authentication failed: Bad Credentials
- Please enter your username:
- hi
- Please enter your password:
- hi
- Successfully authenticated. Security context contains: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@441d0230: Principal: hi; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ROLE_USER
Web 应用中的验证 Authentication in a Web Application
考虑典型的 Web 应用程序的身份验证过程:
您访问主页, 然后单击链接.
请求转到服务器, 服务器确定您已请求受保护的资源.
由于您目前尚未通过身份验证, 因此服务器会发回一个响应, 指示您必须进行身份验证. 响应将是 HTTP 响应代码, 或重定向到特定的 Web 页面.
根据身份验证机制, 您的浏览器将重定向到特定的 Web 页面, 以便您可以填写表单, 或者浏览器将以某种方式检索您的身份(通过 BASIC 身份验证对话框, cookie,X. 509 证书等).
浏览器将向服务器发回响应. 这将是包含您填写的表单内容的 HTTP POST, 或者包含您的身份验证详细信息的 HTTP 标头.
接下来, 服务器将决定所呈现的凭证是否有效. 如果它们有效, 则下一步将会发生. 如果它们无效, 通常会要求您的浏览器再次尝试(因此您将返回上面的第二步).
将重试您进行身份验证过程的原始请求. 希望您已通过足够授权的权限进行身份验证以访问受保护资源. 如果您有足够的访问权限, 请求将成功. 否则, 您将收到 HTTP 错误代码 403, 这意味着 "禁止".
ExceptionTranslationFilter
ExceptionTranslationFilter 是一个 Spring Security 过滤器, 负责检测抛出的任何 Spring Security 异常. AbstractSecurityInterceptor 通常会抛出此类异常, 这是授权服务的主要提供者.
AuthenticationEntryPoint
AuthenticationEntryPoint 负责上面列表中的第三步. 可以想象, 每个 Web 应用程序都有一个默认的身份验证策略(好吧, 这可以像 Spring Security 中的几乎所有其他配置一样配置, 但现在让我们保持简单). 每个主要身份验证系统都有自己的 AuthenticationEntryPoint 实现, 通常执行步骤 3 中描述的操作之一.
在请求之间 SecurityContext
在 Spring Security 中, 在请求之间存储 SecurityContext 的责任落在 SecurityContextPersistenceFilter 上, 默认情况下, 该上下文将上下文存储为 HTTP 请求之间的 HttpSession 属性.
许多其他类型的应用程序 (例如, 无状态 RESTful Web 服务) 不使用 HTTP 会话, 并将在每个请求上重新进行身份验证. 但是, 链中包含 SecurityContextPersistenceFilter 以确保在每次请求后清除 SecurityContextHolder 仍然很重要.
授权 / 访问控制 Access-Control (Authorization) in Spring Security
负责在 Spring Security 中做出访问控制决策的主界面是 AccessDecisionManager. 它有一个 decide 方法, 它接受一个代表请求访问的主体的 Authentication 对象, 一个 "安全对象"(见下文)和一个适用于该对象的安全元数据属性列表 (例如角色列表) 这是获得访问所必需的.
aop
可以选择使用 AspectJ 或 Spring AOP 执行方法授权, 也可以选择使用过滤器执行 Web 请求授权. 您可以将这些方法中的零个, 一个, 两个或三个一起使用. 主流使用模式是执行一些 Web 请求授权, 以及服务层上的一些 Spring AOP 方法调用授权.
AbstractSecurityInterceptor
AbstractSecurityInterceptor 为处理安全对象请求提供了一致的工作流程, 通常:
查找与当前请求关联的 "配置属性"
将安全对象, 当前 Authentication 和配置属性提交到 AccessDecisionManager 以进行授权决策
(可选)更改发生调用的 Authentication
允许安全对象调用继续(假设已授予访问权限)
调用返回后, 调用 AfterInvocationManager(如果已配置). 如果调用引发异常, 则不会调用 AfterInvocationManager.
- Configuration Attributes
- RunAsManager
- AfterInvocationManager
- Security interceptors and the "secure object" model
本地化
参考
英文版文档
https://docs.spring.io/spring-security/site/docs/5.0.5.RELEASE/reference/htmlsingle/#overall-architecture
中文版文档
https://www.springcloud.cc/spring-security.html
来源: https://www.cnblogs.com/victor2302/p/11736277.html