From e805a650395ea37e66538f1820ea0c2fefe27db3 Mon Sep 17 00:00:00 2001 From: wu xiangkai Date: Sat, 8 Oct 2022 18:04:38 +0800 Subject: [PATCH] =?UTF-8?q?=E6=97=A5=E5=B8=B8=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- spring/Spring Security/Spring Security.md | 102 +++++++++++++++++++++ 分布式事务/Seata框架/Seata简介.md | 8 ++ 2 files changed, 110 insertions(+) create mode 100644 spring/Spring Security/Spring Security.md create mode 100644 分布式事务/Seata框架/Seata简介.md diff --git a/spring/Spring Security/Spring Security.md b/spring/Spring Security/Spring Security.md new file mode 100644 index 0000000..206cc39 --- /dev/null +++ b/spring/Spring Security/Spring Security.md @@ -0,0 +1,102 @@ +# Spring Security +## Spring Security简介 +Spring Security作为一个安全框架,向使用者提供了用户认证、授权、常规攻击保护等功能。 +## Spring Security自动配置 +默认情况下,在引入Spring Security的启动器依赖之后,Spring Boot自动配置会做如下工作: +- 启用Spring Security的默认配置,创建一个的bean对象,bean对象名称为“springSecurityFilterChain”,bean对象类型为SecurityFilterChain,实现了Filter。该bean对象为负责应用中所有与安全相关的操作(例如验证提交的username和password,保护应用的url等) +- 创建一个UserDetailsService的bean对象,并且产生一个为”user“的username和一个随机产生的password,随机产生的password会输出在console日志中 +- 将名为springSecurityFilterChain的bean对象注册到servlet容器中,用来对每个servlet请求进行处理 +> Spring Security会通过Spring Security会通过BCtypt(Hash解密算法)来对密码的存储进行保护 + +## Spring Security结构 +### DelegatingFilterProxy +Spring提供了Filter的一个实现类DelegatingFilterProxy,其将Servlet容器的生命周期和Spring的ApplicationContext连接在一起。 +***DelegatingFilterProxy会通过标准的servlet容器机制被注册,但是将所有工作都委托给Spring容器中实现了Filter的bean对象***。 +> DelegatingFilterProxy会在ApplicationContext中查找实现了Filter的bean对象,并且调用该bean对象的doFilter方法 +> ```java +> public void doFilter(ServletRequest request, +> ServletResponse response, FilterChain chain) { +> // Lazily get Filter that was registered as a Spring Bean +> // For the example in DelegatingFilterProxy delegate is an instance of Bean Filter0 +> Filter delegate = getFilterBean(someBeanName); +> // delegate work to the Spring Bean +> delegate.doFilter(request, response); +> } +> ``` + +### FilterChainProxy +Spring Security支持FilterChainProxy,FilterChainProxy是一个由Spring Security提供的特殊Filter,FilterChainProxy通过SecurityFilterChain允许向多个Filters委托工作。 +***FilterChainProxy是一个bean对象,通过被包含在DelegatingFilterProxy中。*** + +### SecurityFilterChain +SecurityFilterChain通常被FilterChainProxy使用,用来决定在该次请求中调用那些Spring Security Filters。 + +### SecurityFilters +Security Filters通过SecurityFilterChain API被插入到FilterChainProxy中。 +### 处理Security异常 +ExceptionTranslationFilter将认证异常和权限异常翻译为http response。 +> ExceptionTranslationFilter被插入到FilterChainProxy中,作为SecurityFilterChain中的一个。 +> 如果应用程序没有抛出AccessDeniedException或AuthenticationException,那么ExceptionTranslationFilter并不会做任何事情。 + +```java +// ExceptionTranslationFilter的伪代码 +try { + filterChain.doFilter(request, response); +} catch (AccessDeniedException | AuthenticationException ex) { + if (!authenticated || ex instanceof AuthenticationException) { + startAuthentication(); + } else { + accessDenied(); + } +} +``` + +## Spring Security身份认证的结构 +### SecurityContextHolder +Spring Security身份认证的核心模型,SecurityContextHolder包含有SecurityContext。 +> Spring Security将被认证用户的详细信息(details)存储在SecurityContextHolder中。Spring Security不在乎该SecurityContextHolder是如何被填充的,只要该SecurityContextHolder有值,那么其将会被用作当前已经被认证的用户。 + +> ***将用户标识为已认证的最简单的方法是为该用户设置SecurityContextHolder。*** + +```java +// 设置SecurityContextHolder +SecurityContext context = SecurityContextHolder.createEmptyContext(); +Authentication authentication = + new TestingAuthenticationToken("username", "password", "ROLE_USER"); +context.setAuthentication(authentication); + +SecurityContextHolder.setContext(context); +``` +默认情况下,SecurityContextHolder通过ThreadLocal来存储SecurityContext,故而SecurityContext对于位于同一线程之下的方法来说都可以访问。 +> 使用ThreadLocal来存储SecurityContext是相当安全的,如果想要在该已认证主体的请求被处理完成之后清除SecurityContext,Spring Security中的FilterChainProxy会保证该SecurityContext被清除。 + +### SecurityContext +SecurityContext从SecurityContextHolder中获得,SecurityContext中含有Authentication对象。 + +### Authentication +Authentication在Spring Security中具有两个目的: +- 作为AuthenticationManager的输入,用于提供待认证用户的认证凭证。当用于该场景下时,isAuthenticated()方法返回值应该为false +- 代表当前已经认证过的用户。当前的Authentication可以从SecurityContext中获取,而默认情况下SecurityContext是存储在ThreadLocal中的 + +Authentication含有如下部分: +- 主体(principal):用于标识用户,当通过username/password进行认证时,其通常是UserDetails类的实例 +- 凭据(credentials):通常是password,在许多场景下凭据会在用户认证成功之后被清空,为了保证凭据不会被泄露 +- 权限(authorities):该GrantedAuthority集合是用户被授予的高层次许可。许可通常是用户角色或者作用域范围。 + +### GrantedAuthority +GrantedAuthority是用户被授予的高层次许可,譬如用户角色或者作用域范围。 +GrantedAuthority可以通过Authentication.getAuthorities()方法来获得,该方法会返回一个GrantedAuthentication的集合。每个GrantedAuthentication都是一项被授予该用户的权限。 + +### AuthenticationManager +AuthenticationManager的API定义了Security Filters如何来执行身份认证。对于身份认证返回的Authentication,会被调用AuthenticationManager的controller设置到SecurityContextHolder中。 +> AuthenticationManager的实现可以是任何类,但是最通用的实现仍然是ProviderManager + +### ProviderManager +ProviderManager是AuthenticationManager的最通用实现。ProviderManager将工作委托给一系列AuthenticationProvider。 +> 对于每个ProviderManager,都可以决定将该认证标识为成功、失败,或者将认证工作委托给下游AuthenticationProvider。 +> 如果所有的AuthenticationProvider都没有将该认证标识为成功或者失败,那么整个认证流程失败,并且抛出ProviderNotFoundException异常。 +> ProviderNotFoundException是一个特殊的AuthenticationException,该异常代表对传入Authentication的类型并没有配置该类型的ProviderManager + +> 在实践中,每个AuthenticationProvider知道如何处理一种特定类型的Authentication + +默认情况下,ProviderManager在认证请求成功后会尝试清除返回的Authentication对象中任何敏感的凭据信息,这将会保证password等敏感信息保存时间尽可能地短,减少泄露的风险。 \ No newline at end of file diff --git a/分布式事务/Seata框架/Seata简介.md b/分布式事务/Seata框架/Seata简介.md new file mode 100644 index 0000000..7fd6eb5 --- /dev/null +++ b/分布式事务/Seata框架/Seata简介.md @@ -0,0 +1,8 @@ +# Seata +## Seata简介 +Seata是一款开源的分布式事务解决方案,向客户提供了高性能且简单易用的分布式事务服务。Seata向客户提供了AT,TCC,SAGA,XA等模式。 +## AT模式 +### 前提 +- 基于的关系型数据库要支持本地事务的acid +- java应用,通过jdbc访问数据库 +- \ No newline at end of file