README_CN.md 11.9 KB
Newer Older
1 2 3 4 5 6
<p align="center">
  <a href="https://su.usthe.com">
    <img alt="sureness" src="./docs/_media/hat-128.svg">
  </a>
</p>

sinat_25235033's avatar
sinat_25235033 已提交
7
# <font size="14p">sureness</font> <font size="5p">  | [English Documentation](README.md)</font>
8

9
> 面向`restful api`的高性能认证鉴权框架   
10 11 12 13 14 15

[![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html) 
![GitHub pull request check contexts](https://img.shields.io/github/status/contexts/pulls/tomsun28/sureness/8?label=pull%20checks) 
[![Gitter](https://img.shields.io/gitter/room/usthe/sureness?label=sureness&color=orange&logo=gitter&logoColor=red)](https://gitter.im/usthe/sureness) 
![GitHub Release Date](https://img.shields.io/github/release-date/tomsun28/sureness?color=blue&logo=figshare&logoColor=red) 

sinat_25235033's avatar
sinat_25235033 已提交
16 17
**主页: [usthe.com/sureness](https://usthe.com/sureness), 备用网站: [su.usthe.com](https://su.usthe.com/)**  

sinat_25235033's avatar
sinat_25235033 已提交
18

19
## 📫 背景         
20

sinat_25235033's avatar
sinat_25235033 已提交
21 22 23
在主流的前后端分离架构中,如何通过有效快速的认证鉴权来保护后端提供的`restful api`变得尤为重要。对现存框架,不原生支持`rest``apache shiro`
还是深度绑定`spring`,较慢性能,学习曲线陡峭的`spring security`,或多或少都不是我们的理想型。   
于是乎`sureness`诞生了,我们希望能解决这些,提供一个面向**restful api****无框架依赖**,可以**动态修改权限****多认证策略****更快速度****易用易扩展**的认证鉴权框架。      
24

25
## 🎡 <font color="green">介绍</font>
26

sinat_25235033's avatar
sinat_25235033 已提交
27 28 29 30
> `sureness` 是我们在深度使用权限框架 `apache shiro` 之后,吸取其一些优点全新设计开发的一个认证鉴权框架  
>  面向 `restful api` 的认证鉴权,基于 `rbac` (用户-角色-资源)主要关注于对 `restful api` 的安全保护  
>  无特定框架依赖(本质就是过滤器处拦截判断,已有`springboot,quarkus,javalin,ktor`等集成样例)  
>  支持动态修改权限配置(动态修改配置每个`rest api`谁有权访问)    
sinat_25235033's avatar
sinat_25235033 已提交
31
>  支持主流`http`容器  `servlet` 和 `jax-rs`  
32
>  支持多种认证策略, `jwt, basic auth, digest auth` ... 可扩展自定义支持的认证方式   
sinat_25235033's avatar
sinat_25235033 已提交
33
>  [基于改进的字典匹配树拥有的高性能](#高性能匹配 )    
sinat_25235033's avatar
sinat_25235033 已提交
34
>  良好的扩展接口, 样例和文档  
35

36
>`sureness`的低配置,易扩展,不耦合其他框架,希望能帮助开发者对自己的项目多场景快速安全的进行保护   
37

38
##### 🔍 框架对比     
sinat_25235033's avatar
sinat_25235033 已提交
39 40 41 42 43 44 45 46 47 48

| ~         | sureness | shiro | spring security |
| ---       | ---      | ---   | ---  |
| **多框架支持**  | 支持      | 需改动支持   | 不支持 |
| **restful api** | 支持 | 需改动支持   | 支持 |
| **过滤链匹配**  | 优化的字典匹配树 | ant匹配 | ant匹配 |
| **注解支持**    | 支持      | 支持      | 支持 |
| **servlet**    | 支持      | 支持      | 支持|
| **jax-rs**     | 支持      | 不支持    | 不支持|
| **权限动态修改** | 支持 | 需改动支持 | 需改动支持|
sinat_25235033's avatar
sinat_25235033 已提交
49
| **性能速度** | 较快 | 较慢 | 较慢|
sinat_25235033's avatar
sinat_25235033 已提交
50
| **学习曲线** | 简单 | 简单 | 陡峭|  
sinat_25235033's avatar
sinat_25235033 已提交
51

52
##### 📈 基准性能测试  
53 54 55

![benchmark](docs/_images/benchmark_cn.png)  

sinat_25235033's avatar
sinat_25235033 已提交
56 57
**基准测试显示sureness对比无权限框架应用损耗0.026ms性能,shiro损耗0.088ms,spring security损耗0.116ms,
相比之下sureness基本不消耗性能,且性能(参考TPS损耗)是shiro的3倍,spring security的4倍**     
sinat_25235033's avatar
sinat_25235033 已提交
58
**性能差距会随着api匹配链的增加而进一步拉大**     
59
详见[基准测试](https://github.com/tomsun28/sureness-shiro-spring-security)    
sinat_25235033's avatar
sinat_25235033 已提交
60

61
##### ✌ 框架支持样例    
62

sinat_25235033's avatar
sinat_25235033 已提交
63 64 65 66 67 68
- [x] sureness集成springboot样例(配置文件方案) [sample-bootstrap](sample-bootstrap)   
- [x] sureness集成springboot样例(数据库方案) [sample-tom](sample-tom)  
- [x] sureness集成quarkus样例 [sample-quarkus](samples/quarkus-sureness)  
- [x] sureness集成javalin样例 [sample-javalin](samples/javalin-sureness)    
- [x] sureness集成ktor样例 [sample-ktor](samples/ktor-sureness)   
- [x] sureness集成spring webflux样例 [sample-spring-webflux](samples/spring-webflux-sureness)   
69 70 71
- [x] more samples todo   


72
## 🔨 快速开始  
73

74
#### 🐕 <font color="red">使用前一些约定</font>  
75 76 77 78 79 80 81

- `sureness`尽量简洁,基于`rbac`,只有(角色-资源)的映射,没有(权限)动作映射,即 用户-角色-资源  
- 我们将`restful api`请求视作一个资源,资源格式为: `requestUri===httpMethod`  
  即请求的路径加上其请求方式(`post,get,put,delete...`)作为一个整体被视作一个资源  
  `eg: /api/v2/book===get` `get`方式请求`/api/v2/book`接口数据     
- 角色资源映射: 用户所属角色--角色拥有资源--用户拥有资源(用户就能访问此`api`)   

sinat_25235033's avatar
sinat_25235033 已提交
82
资源路径匹配详见 [URI路径匹配](docs/cn/path-match.md)  
83

84
#### 🐖 项目中加入sureness  
85

sinat_25235033's avatar
sinat_25235033 已提交
86
项目使用`maven``gradle`构建,加入坐标    
87 88 89 90
```
<dependency>
    <groupId>com.usthe.sureness</groupId>
    <artifactId>sureness-core</artifactId>
91
    <version>0.4.6</version>
92 93 94
</dependency>
```
```
95
compile group: 'com.usthe.sureness', name: 'sureness-core', version: '0.4.6'
96 97
```

98
#### 🐵 使用默认配置来配置sureness    
sinat_25235033's avatar
sinat_25235033 已提交
99 100
默认配置使用了文件数据源`sureness.yml`作为账户权限数据源  
默认配置支持了`jwt, basic auth, digest auth`认证  
101
```
sinat_25235033's avatar
sinat_25235033 已提交
102 103 104 105
@Bean
public DefaultSurenessConfig surenessConfig() {
    return new DefaultSurenessConfig();
}
106 107
```

108
#### 🐮 配置权限账户数据源      
sinat_25235033's avatar
sinat_25235033 已提交
109 110

`sureness`认证鉴权,当然也需要我们提供自己的账户数据,角色权限数据等,这些数据可能来自文本,关系数据库,非关系数据库,注解等。  
111
我们提供了数据源接口:`SurenessAccountProvider`, `PathTreeProvider`,用户可以实现此接口实现自定义数据源。  
sinat_25235033's avatar
sinat_25235033 已提交
112

113 114
- `PathTreeProvider`: 资源的数据源接口,实现从数据库,文本等加载数据,加载到对应的资源权限匹配器`DefaultPathRoleMatcher`
- `SurenessAccountProvider`: 用户的账户密钥信息接口,实现从数据库,文本等加载数据,加载到需要账户数据的`processor`
sinat_25235033's avatar
sinat_25235033 已提交
115

116
当使用的是上方默认配置`DefaultSurenessConfig`时,则默认使用文本数据源和注解数据源作为数据提供者。  
sinat_25235033's avatar
sinat_25235033 已提交
117

118 119 120 121
- 文本数据源使用`sureness.yml`配置数据,使用方式详见文档 [默认文本数据源](docs/cn/default-datasource.md)   
- 注解数据源的注解`@RequiresRoles,@WithoutAuth`使用方式详见文档 [注解资源权限数据源](docs/cn/annotation-datasource.md)    

我们提供了代码工程样例:  
sinat_25235033's avatar
sinat_25235033 已提交
122 123
默认文本数据源具体实现,请参考[sureness集成springboot样例(配置文件方案)--sample-bootstrap](https://github.com/tomsun28/sureness/tree/master/sample-bootstrap)   
若权限配置数据来自数据库,请参考[sureness集成springboot样例(数据库方案)--sample-tom](https://github.com/tomsun28/sureness/tree/master/sample-tom)  
sinat_25235033's avatar
sinat_25235033 已提交
124

125
#### 🐐 添加过滤器拦截所有请求    
126

sinat_25235033's avatar
sinat_25235033 已提交
127
`sureness`的本质就拦截所有`rest`请求对其认证鉴权判断。  
128
入口拦截器器实现一般可以是 `filter or spring interceptor`  
sinat_25235033's avatar
sinat_25235033 已提交
129
在拦截器中加入`sureness`的安全过滤器,如下:  
130 131

```
sinat_25235033's avatar
sinat_25235033 已提交
132
SubjectSum subject = SurenessSecurityManager.getInstance().checkIn(servletRequest)
133 134
```

135
#### 🐰 实现认证鉴权相关异常处理流程      
sinat_25235033's avatar
sinat_25235033 已提交
136 137 138

`sureness`使用异常处理流程:  
1. 若认证鉴权成功,`checkIn`会返回包含用户信息的`SubjectSum`对象  
sinat_25235033's avatar
sinat_25235033 已提交
139
2. 若中间认证鉴权失败,`checkIn`会抛出不同类型的认证鉴权异常,用户需根据这些异常来继续后面的流程(返回相应的请求响应)
140

sinat_25235033's avatar
sinat_25235033 已提交
141
这里我们就需要对`checkIn`抛出的异常做自定义处理,认证鉴权成功直接通过,失败抛出特定异常进行处理,如下:  
142 143

```
sinat_25235033's avatar
sinat_25235033 已提交
144 145 146 147 148 149 150 151 152 153 154 155 156
try {
    SubjectSum subject = SurenessSecurityManager.getInstance().checkIn(servletRequest);
} catch (ProcessorNotFoundException | UnknownAccountException | UnsupportedSubjectException e4) {
    // 账户创建相关异常 
} catch (DisabledAccountException | ExcessiveAttemptsException e2 ) {
    // 账户禁用相关异常
} catch (IncorrectCredentialsException | ExpiredCredentialsException e3) {
    // 认证失败相关异常
} catch (UnauthorizedException e5) {
    // 鉴权失败相关异常
} catch (SurenessAuthenticationException | SurenessAuthorizationException e) {
    // 其他自定义异常
}
157 158
```

sinat_25235033's avatar
sinat_25235033 已提交
159 160
异常详见 [默认异常类型](docs/cn/default-exception.md)  

161 162
**HAVE FUN**  

sinat_25235033's avatar
sinat_25235033 已提交
163 164
> 如果这个[快速开始]对您不是很友好,可以参考这篇[一步一步搭建](docs/cn/step-by-step.md),里面一步一步详细介绍了使用sureness搭建一个完整功能认证鉴权项目的步骤。  

165
## 🥐 进阶扩展  
166

167
`sureness`支持自定义`subject`,自定义`subjectCreator`注册,自定义`processor`处理器等   
168

169 170 171 172 173 174 175
进阶自定义扩展之前我们先来了解下sureness的大致流程:  

![flow](docs/_images/flow-cn.png)   

如上面流程,Subject被SubjectCreate根据request请求体所创造,不同的认证鉴权处理器Processor来处理所支持的Subject。  

sureness提供了下面这些常用接口作为扩展点:  
176 177 178 179 180 181 182

- `Subject`: 认证鉴权对象接口,提供访问对象的账户密钥,请求资源,角色等信息  
- `SubjectCreate`: 创建`Subject`接口,根据请求内容创建不同类型的`Subject`对象    
- `Processor`: `Subject`处理接口,根据Subject信息,进行认证鉴权  
- `PathTreeProvider`: 资源的数据源接口,实现从数据库,文本等加载数据  
- `SurenessAccountProvider`: 用户的账户密钥信息接口,实现从数据库,文本等加载数据  

183
扩展文档详见 [扩展点](docs/cn/extend-point.md)  
184

185
1. 🥊 **自定义subject**  
186

187 188 189 190
实现`Subject`接口,添加自定义的`subject`内容  
实现`SubjectCreate`接口方法,自定义subjectCreator创建出自定义的`subject`  
实现`BaseProcessor`接口,自定义processor支持处理自定义的`subject`    
详见 [自定义Subject](docs/cn/custom-subject.md)   
191

192
2. 🔫 **自定义subjectCreator**   
193

194 195
实现`SubjectCreate`接口方法,根据request请求的内容创建出对应需要的的`subject`  
详见 [自定义SubjectCreate](docs/cn/custom-subject-creator.md)   
196

197
3. 🪓 **自定义processor**  
198

199 200 201
实现`BaseProcessor`接口,设置支持的`subject`,实现处理该`subject`的认证鉴权逻辑   
详见 [自定义Processor](docs/cn/custom-processor.md)   

202
4. 🏹 **自定义数据源**  
203 204 205 206

实现 `PathTreeProvider`的接口, 加载到对应的资源权限匹配器`DefaultPathRoleMatcher`
实现 `SurenessAccountProvider`的接口,加载到需要账户数据的`processor`
详见 [自定义数据源](docs/cn/custom-datasource.md)   
207

sinat_25235033's avatar
sinat_25235033 已提交
208
具体扩展实践请参考 [sureness集成springboot样例(数据库方案)--sample-tom](sample-tom)  
209 210


211
## 🙋 参与贡献  
sinat_25235033's avatar
sinat_25235033 已提交
212
非常欢迎参与项目贡献。对项目代码有疑问或者建议请直接联系 @tomsun28  
213 214 215

仓库的组成部分:  
- [sureness的核心代码--sureness-core](core)  
sinat_25235033's avatar
sinat_25235033 已提交
216 217
- [使用sureness集成springboot搭建权限项目(配置文件方案)--sample-bootstrap](sample-bootstrap)  
- [使用sureness集成springboot搭建权限项目(数据库方案)--sample-tom](sample-tom)  
218 219
- [各个框架使用sureness的样例项目(javalin,ktor,quarkus)--samples](samples)  

220
#### 💪 高性能匹配      
221

222
![pathRoleMatcher](docs/_images/PathRoleMatcher.svg)  
223

224
## 💡 更多相关     
sinat_25235033's avatar
sinat_25235033 已提交
225 226 227

相关文章:  
[restful api 权限设计 - 初探一](https://segmentfault.com/a/1190000038360856)   
sinat_25235033's avatar
sinat_25235033 已提交
228
[restful api 权限设计 - 快速搭建权限项目-配置文件方案](https://segmentfault.com/a/1190000039075245)    
sinat_25235033's avatar
sinat_25235033 已提交
229
[restful api 权限设计 - sureness集成springboot样例-数据库方案](https://segmentfault.com/a/1190000039191172)     
sinat_25235033's avatar
sinat_25235033 已提交
230 231 232 233 234 235 236

相关视频:  
[bilibili-10分钟搭建一个完整认证鉴权项目,原谅第一次的川普和英语](https://www.bilibili.com/video/bv1EU4y1s7Sz)    

QQ交流群:390083213    
微信公众号:sureness   

237
## 🛡️ License  
238
[`Apache License, Version 2.0`](https://www.apache.org/licenses/LICENSE-2.0.html)