README.md 9.5 KB
Newer Older
sinat_25235033's avatar
sinat_25235033 已提交
1
# sureness - 面向restful api的认证鉴权  
sinat_25235033's avatar
sinat_25235033 已提交
2

sinat_25235033's avatar
sinat_25235033 已提交
3
> A simple and efficient open-source jvm security framework that focus on the protection of restful api.
sinat_25235033's avatar
sinat_25235033 已提交
4

sinat_25235033's avatar
sinat_25235033 已提交
5 6 7 8
[![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) 
9

sinat_25235033's avatar
sinat_25235033 已提交
10 11 12
**若主页[usthe.com/sureness](https://usthe.com/sureness) 访问不了,请使用备用网站: [su.usthe.com](https://su.usthe.com/)**  

[英文文档 -> English Documentation](README_EN.md)   
sinat_25235033's avatar
sinat_25235033 已提交
13

sinat_25235033's avatar
sinat_25235033 已提交
14
## Background  
sinat_25235033's avatar
sinat_25235033 已提交
15 16 17
现在很多网站都进行了前后端分离,后端提供rest api,前端调用接口获取数据渲染。这种架构下如何保护好后端所提供的rest api使得更加重视。  
api的保护可以认为:认证-请求携带的认证信息是否校验通过,鉴权-认证通过的用户拥有指定api的权限才能访问此api。然而不仅于此,什么样的认证策略, jwt, basic,digest,oauth还是多支持, 权限配置是写死代码还是动态配置,我想动态赋权怎么办,云原生越来越火用的框架是quarkus等新秀不是spring生态咋弄,http实现不是servlet而是jax-rs规范咋整, to be or not to be, this is a question

sinat_25235033's avatar
sinat_25235033 已提交
18
> 目前`java`主流的权限框架有`shiro,spring security`, 下面对于它们的探讨都是个人之见,接受纠正   
sinat_25235033's avatar
sinat_25235033 已提交
19
> `shiro`对于`restful api`原生支持不太友好,需要改写一些代码,2年前一个项目 [booshiro](https://gitee.com/tomsun28/bootshiro) 就是改造`shiro`,使其在过滤链就能匹配不同的`rest`请求进行权限校验,之后给`shiro commit`几次`pr`,`fix`其在过滤链匹配时的危险漏洞,总的来说`shiro`很强大但其起源并非面向`web`,对`restful`不是很友好    
sinat_25235033's avatar
sinat_25235033 已提交
20 21 22
> `spring security`很强大,与`spring`深度集成,离开`spring`,比如`javalin`和之前用过的`osgi`框架`karaf`就用不了了  
> 如果不用注解配置,它们都会在链式匹配这块,用请求的url和配置的链一个一个`ant`匹配(匹配过程中会有缓存等提高性能),但匹配的链过多时还是比较耗性能(根据算法时间复杂度判断,暂未测试验证)    
> 我们希望能解决这些,提供一个**针对restful api**,**无框架依赖**,可以**动态修改权限**,**多认证策略**,**更快速度**,**易用**的认证鉴权框架    
sinat_25235033's avatar
sinat_25235033 已提交
23

sinat_25235033's avatar
sinat_25235033 已提交
24 25
## <font color="green">Introduction</font>

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

sinat_25235033's avatar
sinat_25235033 已提交
35
>`sureness`的低配置,易扩展,不耦合其他框架,能使开发者对自己的项目多场景快速安全的进行保护   
sinat_25235033's avatar
sinat_25235033 已提交
36

sinat_25235033's avatar
sinat_25235033 已提交
37 38 39 40 41 42
##### Framework Sample Support  

- [x] spring [sample-bootstrap](sample-bootstrap)   
- [x] springboot [sample-tom](sample-tom)  
- [x] quarkus [sample-quarkus](samples/quarkus-sureness)  
- [x] javalin [sample-javalin](samples/javalin-sureness)    
43 44
- [x] ktor [sample-ktor](samples/ktor-sureness)   
- [x] spring webflux [spring-webflux-sureness](samples/spring-webflux-sureness)  
sinat_25235033's avatar
sinat_25235033 已提交
45 46 47
- [x] more samples todo   


sinat_25235033's avatar
sinat_25235033 已提交
48
## 快速开始  
sinat_25235033's avatar
sinat_25235033 已提交
49

sinat_25235033's avatar
sinat_25235033 已提交
50
##### <font color="red">使用前一些约定</font>  
sinat_25235033's avatar
sinat_25235033 已提交
51

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

sinat_25235033's avatar
sinat_25235033 已提交
58 59
资源路径匹配详见 [url路径匹配](docs/path-match.md)  

sinat_25235033's avatar
sinat_25235033 已提交
60
##### 项目中加入sureness  
sinat_25235033's avatar
sinat_25235033 已提交
61

sinat_25235033's avatar
sinat_25235033 已提交
62
1. 项目使用`maven`构建,加入`maven`坐标  
sinat_25235033's avatar
sinat_25235033 已提交
63 64 65 66
```
<dependency>
    <groupId>com.usthe.sureness</groupId>
    <artifactId>sureness-core</artifactId>
sinat_25235033's avatar
sinat_25235033 已提交
67
    <version>0.0.2.8</version>
sinat_25235033's avatar
sinat_25235033 已提交
68 69
</dependency>
```
sinat_25235033's avatar
sinat_25235033 已提交
70

sinat_25235033's avatar
sinat_25235033 已提交
71
2. 项目使用`gradle`构建,`gradle`坐标  
sinat_25235033's avatar
sinat_25235033 已提交
72
```
sinat_25235033's avatar
sinat_25235033 已提交
73
compile group: 'com.usthe.sureness', name: 'sureness-core', version: '0.0.2.8'
sinat_25235033's avatar
sinat_25235033 已提交
74
```
75

sinat_25235033's avatar
sinat_25235033 已提交
76 77 78 79 80 81
3. 项目为普通工程,加入`sureness-core.jar`依赖  
```
在 mvnrepository 下载jar  
https://mvnrepository.com/artifact/com.usthe.sureness/sureness-core
```

sinat_25235033's avatar
sinat_25235033 已提交
82
##### 添加拦截所有请求的过滤器入口  
sinat_25235033's avatar
sinat_25235033 已提交
83 84 85

入口拦截器器实现一般可以是 `filter or spring interceptor`  
在拦截器加入sureness的安全过滤器,如下:  
sinat_25235033's avatar
sinat_25235033 已提交
86
入口,一般放在拦截所有请求的`filter`:  
sinat_25235033's avatar
sinat_25235033 已提交
87

sinat_25235033's avatar
sinat_25235033 已提交
88 89 90 91
```
SurenessSecurityManager.getInstance().checkIn(servletRequest)
```

sinat_25235033's avatar
sinat_25235033 已提交
92
##### 实现相关异常处理  
sinat_25235033's avatar
sinat_25235033 已提交
93 94 95

`sureness`使用异常处理流程,我们需要对`checkIn`抛出的异常做自定义处理,  
安全过滤器,认证鉴权成功直接通过,失败抛出特定异常,捕获异常,如下: 
sinat_25235033's avatar
sinat_25235033 已提交
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112

```
        try {
            SubjectSum subject = SurenessSecurityManager.getInstance().checkIn(servletRequest);
        } catch (ProcessorNotFoundException | UnknownAccountException | UnsupportedSubjectException e4) {
            // 账户创建相关异常 
        } catch (DisabledAccountException | ExcessiveAttemptsException e2 ) {
            // 账户禁用相关异常
        } catch (IncorrectCredentialsException | ExpiredCredentialsException e3) {
            // 认证失败相关异常
        } catch (UnauthorizedException e5) {
            // 鉴权失败相关异常
        } catch (RuntimeException e) {
            // 其他自定义异常
        }
```

sinat_25235033's avatar
sinat_25235033 已提交
113
异常详见 [默认异常](docs/default-exception.md)  
sinat_25235033's avatar
sinat_25235033 已提交
114

sinat_25235033's avatar
sinat_25235033 已提交
115
##### 加载配置数据  
sinat_25235033's avatar
sinat_25235033 已提交
116

sinat_25235033's avatar
sinat_25235033 已提交
117
`sureness`认证鉴权,当然也需要我们配置自己的配置数据 - 账户数据,角色权限数据等  
sinat_25235033's avatar
sinat_25235033 已提交
118 119 120
这些配置数据可能来自文本,关系数据库,非关系数据库  
我们提供了配置数据接口`SurenessAccountProvider`, `PathTreeProvider`, 用户可以实现此接口实现自定义配置数据源  
当前我们也提供默认文本形式的配置数据实现 `DocumentResourceDefaultProvider`, 用户可以配置`sureness.yml`来配置数据  
sinat_25235033's avatar
sinat_25235033 已提交
121
默认文本数据源`sureness.yml`配置详见文档 [默认数据源](docs/default-datasource.md)  
122

sinat_25235033's avatar
sinat_25235033 已提交
123 124 125
我们提供了使用代码`DEMO`
默认文本数据源具体实现,请参考[使用sureness10分钟搭建权限项目--sample-bootstrap](https://github.com/tomsun28/sureness/tree/master/sample-bootstrap)   
若权限配置数据来自数据库,请参考[使用sureness30分钟搭建权限项目--sample-tom](https://github.com/tomsun28/sureness/tree/master/sample-tom)  
sinat_25235033's avatar
sinat_25235033 已提交
126

sinat_25235033's avatar
sinat_25235033 已提交
127
**HAVE FUN**  
sinat_25235033's avatar
sinat_25235033 已提交
128

sinat_25235033's avatar
sinat_25235033 已提交
129
## 进阶扩展  
sinat_25235033's avatar
sinat_25235033 已提交
130

sinat_25235033's avatar
sinat_25235033 已提交
131 132 133 134 135 136 137 138 139 140 141 142 143
如果了解 [处理流程](#处理流程),就大概知道`sureness`提供的扩展点    
`sureness`支持自定义`subject`,自定义`subjectCreator`注册,自定义`processor`处理器等  

扩展之前需要了解以下接口:  

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

`sureness`大致流程:  

sinat_25235033's avatar
sinat_25235033 已提交
144
![flow](/docs/_images/flow-cn.png)  
sinat_25235033's avatar
sinat_25235033 已提交
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161

1. **自定义数据源**  

实现 `PathTreeProvider`的接口, 加载到`DefaultPathRoleMatcher`
实现 `SurenessAccountProvider`的接口,加载到需要的`processor`

2. **自定义subject**  

实现`Subject`接口,添加自定义的`subject`内容  
实现`SubjectCreate`接口方法,创建出自定义的`subject`  
实现`Processor`接口,支持处理自定义的`subject`    

3. **自定义processor**  

一个`subject`当然也可以被不同的`processor`处理,所以可以单独自定义`processor`   
实现`Processor`接口,设置支持的`subject`,实现处理该`subject`的逻辑  

sinat_25235033's avatar
sinat_25235033 已提交
162

sinat_25235033's avatar
sinat_25235033 已提交
163
具体扩展实践请参考 [使用sureness30分钟搭建权限项目--sample-tom](sample-tom)  
sinat_25235033's avatar
sinat_25235033 已提交
164 165


sinat_25235033's avatar
sinat_25235033 已提交
166
## 参与贡献  
sinat_25235033's avatar
sinat_25235033 已提交
167
非常欢迎参与项目贡献,帮助sureness走得更远更好。对项目代码有疑问或者建议请直接联系 @tomsun28  
sinat_25235033's avatar
sinat_25235033 已提交
168 169 170 171 172

仓库的组成部分:  
- [sureness的核心代码--sureness-core](core)  
- [使用sureness10分钟搭建权限项目--sample-bootstrap](sample-bootstrap)  
- [使用sureness30分钟搭建权限项目--sample-tom](sample-tom)  
sinat_25235033's avatar
sinat_25235033 已提交
173
- [各个框架使用sureness的样例项目(javalin,ktor,quarkus)--samples](samples)  
sinat_25235033's avatar
sinat_25235033 已提交
174

sinat_25235033's avatar
sinat_25235033 已提交
175 176 177 178
##### 高性能匹配      

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

sinat_25235033's avatar
sinat_25235033 已提交
179
##### 处理流程   
sinat_25235033's avatar
sinat_25235033 已提交
180 181 182

![sureness-core](/docs/_images/sureness-core.svg)  

sinat_25235033's avatar
sinat_25235033 已提交
183
## License  
sinat_25235033's avatar
sinat_25235033 已提交
184
[`Apache License, Version 2.0`](https://www.apache.org/licenses/LICENSE-2.0.html)