From 542b607a8b4bf82d4f70df3252394252f9d797de Mon Sep 17 00:00:00 2001 From: many2many <6168830@qq.com> Date: Mon, 13 May 2024 14:59:55 +0800 Subject: [PATCH] [add]docs --- docs/guides/JWT.md | 52 ++++++++++ docs/guides/Restful风格系统开发指导.md | 57 +++++++++++ docs/guides/git.md | 40 ++++++++ docs/guides/spring security.md | 134 +++++++++++++++++++++++++ 4 files changed, 283 insertions(+) create mode 100644 docs/guides/JWT.md create mode 100644 docs/guides/Restful风格系统开发指导.md create mode 100644 docs/guides/git.md create mode 100644 docs/guides/spring security.md diff --git a/docs/guides/JWT.md b/docs/guides/JWT.md new file mode 100644 index 0000000..e059660 --- /dev/null +++ b/docs/guides/JWT.md @@ -0,0 +1,52 @@ +## JWT + +JSON Web Token (JWT)是一个开放标准(RFC 7519),它定义了一种紧凑的、自包含的方式,用于作为JSON对象在各方之间安全地传输信息。该信息可以被验证和信任,因为它是数字签名的。 + +由于其轻量级和易于使用的特性,JWT在现代的Web应用中非常流行,尤其是在需要跨域认证的场景中。 + +### JWT的组成 + +JWT由三部分组成,用点`.`分隔,形成`header.payload.signature`的结构: + +1. **Header(头部)**:通常由两部分组成:算法(alg)和令牌类型(typ)。例如:`{"alg":"HS256","typ":"JWT"}`。 + +2. **Payload(负载)**:包含所谓的“Claims”,即声明。声明可以是注册声明,也可以是公开的声明。注册声明是预定义的声明,如`iss`(发行者),`sub`(主题),`aud`(观众),`exp`(过期时间),`iat`(签发时间),`jti`(JWT的唯一身份标识)等。公开的声明可以由发行者自行定义。 + +3. **Signature(签名)**:是一个使用头部中指定的算法对前两部分进行签名的结果。签名用于验证消息在传递过程中没有被篡改,并且,如果使用了私钥签名,还可以验证JWT的发行者。 + +### JWT的工作流程 + +1. **用户认证**:用户使用用户名和密码在客户端进行认证。 + +2. **认证服务器验证**:服务器验证用户的凭据,如果验证成功,服务器会生成一个JWT。 + +3. **发送JWT**:服务器将JWT发送回客户端。 + +4. **存储JWT**:客户端可以将其存储在本地存储(如LocalStorage)、SessionStorage或Cookies中。 + +5. **发送请求**:客户端在每次请求到受保护资源时,将JWT发送到服务器。 + +6. **服务器验证**:服务器接收到JWT后,会验证其签名的有效性,并检查如`exp`(过期时间)等声明,以确保JWT没有过期。 + +7. **访问资源**:如果JWT有效,服务器允许客户端访问请求的资源。 + +8. **刷新令牌**:如果JWT过期,客户端可以使用刷新令牌(如果存在)来获取新的JWT。 + +### 示例 + +假设一个用户登录了一个网站,以下是JWT的工作流程: + +1. 用户输入用户名和密码。 +2. 网站将这些凭据发送到服务器。 +3. 服务器验证凭据,如果验证通过,生成一个JWT。 +4. 服务器将JWT发送回用户。 +5. 用户将JWT存储在浏览器的LocalStorage中。 +6. 用户想要访问一个受保护的页面。 +7. 用户的浏览器发送一个请求到服务器,并将JWT作为请求的一部分发送。 +8. 服务器验证JWT的签名,检查`exp`声明以确保它没有过期。 +9. 如果JWT有效,服务器提供受保护的页面内容。 + +JWT是一种无状态的认证机制,它使得用户状态不需要存储在服务器上,从而减轻了服务器的负担,并且可以跨不同的服务和API进行使用。 + +### 参考 +[深入浅出之JWT(JSON Web Token)](https://zhuanlan.zhihu.com/p/355160217) \ No newline at end of file diff --git a/docs/guides/Restful风格系统开发指导.md b/docs/guides/Restful风格系统开发指导.md new file mode 100644 index 0000000..c3cb0e0 --- /dev/null +++ b/docs/guides/Restful风格系统开发指导.md @@ -0,0 +1,57 @@ +## RESTful架构简要开发指导 + +1. 遵循RESTful设计原则 + + 资源导向:将API视为对资源(如用户、订单、文章等)的操作,每个资源都有唯一的URI(Uniform Resource Identifier)。 + + 无状态:服务器不保留客户端会话状态,每次请求都应包含完成该操作所需的所有信息。 + + 统一接口:使用标准的HTTP方法(GET、POST、PUT、PATCH、DELETE等)来表达对资源的操作意图。 + +2. HTTP方法映射到CRUD操作 + + GET:检索资源(单个或集合)。如GET /users(获取所有用户)、GET /users/123(获取ID为123的用户)。 + + POST:创建新资源。如POST /users,请求体携带新用户信息。 + + PUT:替换整个资源。如PUT /users/123,请求体携带完整更新后的用户信息。 + + PATCH:部分更新资源。如PATCH /users/123,请求体只包含需要更改的属性。 + + DELETE:删除资源。如DELETE /users/123。 + +3. 资源标识与URL结构 + + 使用名词复数表示资源集合:如/users、/orders。 + + 使用唯一标识符访问单个资源:如/users/123、/orders/456。 + + 嵌套资源表示关联关系:如/users/123/orders表示用户ID为123的订单列表。 +4. 数据交换格式 + + 使用JSON作为默认数据格式,设置Content-Type和Accept头为application/json。 + + 定义清晰的数据模型,包括属性名称、数据类型、嵌套结构等。 + +5. 版本控制 + + 在URL中包含版本号:如/v1/users、/v2/orders。 + + 使用Accept头区分版本:如Accept: application/vnd.yourapp.v1+json。 + +6. 安全性与认证授权 + + 实现用户认证:如使用JWT(JSON Web Tokens)或OAuth。客户端在请求头中携带Authorization字段。 + + 实施授权:如使用RBAC(Role-Based Access Control)或其他权限模型。返回401(Unauthorized)、403(Forbidden)等状态码处理未授权访问。 + +7. 错误处理与文档 + + 使用合适的HTTP状态码传达操作结果(如200 OK、400 Bad Request、404 Not Found、500 Internal Server Error等)。 + + 提供详细的错误信息:在响应体中包含错误代码、描述和可能的解决方案。 + + 编写或生成API文档:如使用OpenAPI/Swagger规范,提供接口描述、参数说明、请求示例、响应示例等信息。 + +### 更多参考 +[【RESTful】RESTful API 接口设计规范 | 示例](https://developer.aliyun.com/article/940518) \ No newline at end of file diff --git a/docs/guides/git.md b/docs/guides/git.md new file mode 100644 index 0000000..02575cb --- /dev/null +++ b/docs/guides/git.md @@ -0,0 +1,40 @@ +## 不需要git管理的文件 +Git是一个非常强大的版本控制系统,它允许开发者管理和跟踪代码的历史版本,同时提供多种功能来协助开发团队协作。然而,并非所有文件都应该被纳入版本管理,以确保高效、易于管理和共享。以下是一些通常不需要纳入版本管理的文件: + +1. **编译生成的文件和临时文件**:比如Python的`.pyc`编译文件、JavaScript的`.map`映射文件等。这些文件是构建过程中生成,随着源代码的变化而不断更新,不应该被跟踪。 + +2. **IDE和编辑器的配置文件**:包括Visual Studio Code的`settings.json`、PyCharm的`projectSettings.xml`等。这些配置文件通常包含特定的设置和插件配置,对项目的整体开发环境至关重要,但并不影响实际项目代码。 + +3. **生成的文档或报告**:比如API的Swagger文档、用户手册等,这些文件是随着项目开发的成果,随源代码一起提交给团队成员。它们应该被纳入版本管理,以便在需要时查阅历史版本。 + +4. **日志文件**:特别是生产环境下的日志文件,包含了应用运行时的详细信息和错误信息。这些文件往往非常大,而且随着时间的推移而不断增长,不必要地将它们纳入版本控制可能会占用大量的存储空间和加快仓库的加载速度。 + +对于大多数开发项目,除了代码本身之外的所有文件和目录都应该被纳入版本管理。只有特定的文件或目录才不应该被添加到版本控制中,以保持高效和灵活性。 + +## .gitignore文件 + +`.gitignore`文件是Git用于忽略不需要被版本控制的文件的配置文件。它告诉Git哪些文件和文件夹应该被排除在版本控制之外,从而减少不必要的版本控制系统负担,提高代码管理的效率。 + +`.gitignore`文件通常放在项目根目录下,其内容是一个或多个通配符和正则表达式列表,用于指定哪些文件或目录不应该被Git跟踪和管理。每个行定义了一个规则: + +``` +pattern1 +pattern2 +!/path/to/exclude +``` + +- `pattern1` 和 `pattern2` 是需要忽略的文件或目录名称通配符(如 `*.log`, `.env*`, `build/` 等)。 +- `!/path/to/exclude` 是一个否定规则,用于排除特定路径下的文件或目录。它表示无论前面的规则是否匹配该路径下的文件或目录,都应该被忽略。 + +`.gitignore`文件内容示例: + +``` +# Ignore all log files +*.log +# Ignore any .env file +.env* +# Do not ignore build directory +!/build/ +``` + +通过这种方式,`.gitignore`文件可以灵活地配置项目需要忽略的文件和目录,帮助Git高效地处理和维护版本控制。 \ No newline at end of file diff --git a/docs/guides/spring security.md b/docs/guides/spring security.md new file mode 100644 index 0000000..dcf4568 --- /dev/null +++ b/docs/guides/spring security.md @@ -0,0 +1,134 @@ +# Spring Security 请求处理流程 + +## 1. 客户端请求 +- 用户发起一个访问请求。 + +## 2. 拦截请求 +- 请求被Spring Security的过滤器链拦截。 + +## 3. 执行认证 +- 通过`AuthenticationManager`对用户进行身份认证。 + +## 4. 认证信息处理 +- 认证成功后,`AuthenticationProvider`会生成一个认证令牌。 + +## 5. 授权决策 +- `AccessDecisionManager`根据用户的权限和访问控制列表(ACLs)来做出授权决策。 + +## 6. 执行授权 +- 通过`ExpressionHandler`来处理表达式,决定是否允许访问特定资源。 + +## 7. 访问资源 +- 如果授权成功,用户可以访问资源。 + +## 8. 处理响应 +- 服务器处理请求并将响应返回给客户端。 + + +# Spring Security 6 中可扩展或自定义的核心接口和类 + +## AuthenticationProvider +- 当需要实现自定义的用户身份验证逻辑时,可以实现`AuthenticationProvider`接口。 +- 该接口只有一个方法`authenticate(Authentication)`,用于处理传入的认证请求并返回已认证的`Authentication`对象,或者抛出异常表示认证失败。 + +## UserDetailsService +- 实现`UserDetailsService`接口来提供用户详细信息(如用户名、密码、权限等)的加载逻辑。 +- 这是许多内置`AuthenticationProvider`实现(如`DaoAuthenticationProvider`)的基础,用于从数据源(如数据库、LDAP等)获取用户数据。 + +## PasswordEncoder +- 虽然Spring Security提供了多种预置的密码编码器,但若需使用自定义的密码哈希算法或与现有系统兼容,可以实现`PasswordEncoder`接口。 +- 该接口定义了密码的编码、验证和升级方法。 + +## AccessDecisionVoter +- 在授权决策过程中,可以通过实现`AccessDecisionVoter`接口来创建自定义的投票策略。 +- 这些策略可以根据特定条件(如请求属性、用户属性等)对访问请求进行投票,决定是否允许访问。 + +## AuthenticationEntryPoint +- 当未通过身份验证的用户尝试访问受保护资源时,可以通过实现`AuthenticationEntryPoint`接口来定制如何引导用户进入认证流程,例如重定向到登录页面、返回401 Unauthorized HTTP状态码等。 + +## AuthenticationSuccessHandler / AuthenticationFailureHandler +- 在表单登录或其他认证过程中,可以自定义成功或失败后的处理逻辑,如跳转页面、返回JSON响应等,这需要实现对应的`AuthenticationSuccessHandler`和`AuthenticationFailureHandler`接口。 + +## LogoutSuccessHandler +- 实现`LogoutSuccessHandler`接口来指定用户注销成功后的行为,如重定向至特定页面、清除客户端Cookie等。 + +## TokenValidator / OAuth2UserService (针对API安全) +- 在OAuth2或JWT相关场景下,可能需要实现`TokenValidator`或`OAuth2UserService`等接口来验证和解析令牌,或者提供用户信息。 + +## SecurityFilterChain +- 虽然不直接扩展接口,但在Spring Security 6 中,创建自定义`SecurityFilterChain` bean是配置安全规则的主要方式。 +- 通过`HttpSecurity` DSL,可以精细地定义过滤器链的行为,如添加自定义过滤器、配置特定路径的访问控制等。 + +## ExceptionTranslator / AuthenticationEntryPoint (针对WebFlux) +- 在响应式环境中,可能需要自定义异常转换器或认证入口点来处理特定的安全异常和未认证情况。 + +这些接口和类为开发者提供了丰富的扩展点,使他们能够根据实际需求定制Spring Security的行为。在`WebSecurityConfigurerAdapter`的`configure(HttpSecurity http)`方法中的`http`对象来配置具体的HTTP安全规则,如认证方式、授权规则、异常处理等。 + + +# Spring Security 6 工作过程 + +## 1. 启动与配置 +- 在Spring Boot应用启动时,Spring Security通过自动配置或手动配置的方式初始化其组件和安全规则。 +- 配置可能涉及定义认证提供者(如数据库、LDAP、OAuth等)、用户角色映射、访问控制策略、密码编码器、以及定制过滤器链等。 + +## 2. 构建`SecurityFilterChain` +- Spring Security的核心是构建一个名为`SecurityFilterChain`的过滤器链,它由一系列负责不同安全任务的过滤器组成。 +- 这个过滤链通常通过Java配置类、XML配置或者新的基于WebFlux的DSL方式定义,并按照特定顺序注册到Spring的Web容器中。 + +## 3. 请求处理过程 +- 当客户端发起HTTP请求时,该请求首先会经过`SecurityFilterChain`中的各个过滤器。 +- 过滤器链的工作流程大致如下: + +### a. `WebAsyncManagerIntegrationFilter` +- (可选)如果应用支持异步请求,此过滤器确保异步请求的安全上下文正确传播。 + +### b. `SecurityContextPersistenceFilter` +- 恢复或创建`SecurityContext`(存储认证信息和权限),通常从HTTP会话中加载或新建一个空上下文。 + +### c. `HeaderWriterFilter` +- 添加必要的安全响应头,如防止跨站脚本攻击(XSS)和点击劫持(CSRF)的防护头。 + +### d. `CorsFilter` +- (可选)如果启用,处理跨域资源共享(CORS)请求,确保只有符合CORS策略的请求被允许继续。 + +### e. `LogoutFilter` +- 检查请求是否为注销请求(如 `/logout` URL),如果是,则清除`SecurityContext`并可能执行其他注销逻辑(如清除会话、重定向等)。 + +### f. `OAuth2AuthorizationRequestRedirectFilter` / `OAuth2LoginAuthenticationFilter` +- (可选)对于OAuth2相关的登录请求,这些过滤器将处理授权码的获取和用户认证流程。 + +### g. `UsernamePasswordAuthenticationFilter` +- 处理基于表单提交的用户名/密码认证请求,提取凭据并传递给后续的认证管理器进行验证。 + +### h. `RequestCacheAwareFilter` +- 如果请求需要重新导向到另一个URL以完成认证,此过滤器能缓存原始请求以便认证成功后恢复。 + +### i. `SecurityContextHolderAwareRequestFilter` +- 将请求包装为`SecurityContextHolderAwareRequestWrapper`,使得安全上下文在整个请求生命周期中可访问。 + +### j. `AnonymousAuthenticationFilter` +- 如果当前请求尚未经过认证,但应用允许匿名访问,此过滤器将添加一个匿名`Authentication`对象到`SecurityContext`。 + +### k. `SessionManagementFilter` +- 管理用户会话,如并发会话控制、强制性会话创建等。 + +### l. `ExceptionTranslationFilter` +- 捕获未授权(`AccessDeniedException`)和其他安全相关异常,将其转换为适当的HTTP响应(如401 Unauthorized、403 Forbidden)或重定向到指定的错误页面。 + +### m. `FilterSecurityInterceptor` +- 最终的安全决策点,根据配置的访问控制规则(如`@PreAuthorize`注解、`HttpSecurity` DSL定义的路径权限)检查请求是否被授权。如果请求未通过检查,将触发前面提到的异常处理。 + +### n. `SwitchUserFilter` +- (可选)允许特定用户(如管理员)切换到其他用户的身份来模拟其操作。 + +## 4. 认证与授权 +- 认证过程中,过滤器链中的相关组件会提取请求中的认证信息(如用户名/密码、JWT令牌、OAuth2令牌等),并使用相应的认证提供者进行验证。 +- 验证成功后,一个代表用户身份的`Authentication`对象会被填充并放入`SecurityContext`中。 +- 授权阶段,`FilterSecurityInterceptor`根据已认证用户的角色、权限或其他属性判断其是否有权访问请求的资源。 + +## 5. 响应与清理 +- 如果请求顺利通过所有安全检查,请求将被传递给应用程序的业务逻辑进行处理,并最终返回响应给客户端。 +- 在响应发送给客户端之前,某些过滤器(如`HeaderWriterFilter`)可能还会添加额外的安全响应头。 +- 请求处理完毕后,`SecurityContext`可能被保存回HTTP会话(如果适用)以备后续请求使用。 + +**综上所述**,Spring Security 6 通过构建和执行一个精心设计的过滤器链来对每个进入应用的HTTP请求进行身份验证、授权检查以及必要的异常处理,确保只有经过有效认证且具有足够权限的请求才能访问受保护的资源。