## 简介 * Secure 基于 JWT 封装,每次接收到请求,会拦截到需要鉴权的API信息,并对其请求头携带的Token进行认证。 * 若 Token 过期、不存在、错误,都会导致鉴权失败,继而无法访问到对应的API。 * BladeX 的安全框架 Secure 在[BladeX-Tool](https://git.bladex.vip/blade/BladeX-Tool) 中,有兴趣的小伙伴可以阅读下源码,查看实现原理。 * 本章介绍 Secure 的基本使用方法。 ## 如何通过认证 1. 首先需要访问Auth接口,传入账号名密码,获得授权成功后的信息 2. 启动`AuthApplication`、`UserApplication`、 `LogApplication`、 `SystemApplication`四个服务 ![](../../images/screenshot_1579269619026.png) 3. 调用 [http://localhost/blade-auth/oauth/token](http://localhost/blade-auth/oauth/token) 传入对应参数,如下图所示则说明认证信息获取成功。后续章节将会详细讲到Oauth2,我们先快速调用查看效果,具体调用方式请看:[https://sns.bladex.vip/article-14982.html](https://sns.bladex.vip/article-14982.html) ![](../../images/screenshot_1574305684211.png) ![](../../images/screenshot_1584617184986.png) ![](../../images/screenshot_1584617205489.png) 4. 从返回的Json中取到 `tokenType` 和 `accessToken`,将他们拼接起来并以逗号隔开 5. 设置请求头为`Blade-Auth`,请求头对应的值为 `tokenType` + `' '` + `accessToken` 6. 设置请求头为 `Authorization` 值为 `Basic c3dvcmQ6c3dvcmRfc2VjcmV0`,这个后续章节也会提到。 7. 再次调用 [http://localhost/blade-demo/api/info?name=Chill](http://localhost/blade-demo/api/info?name=Chill) 发现返回 `Hello, My Name Is: Chill` 说明鉴权成功! ![](../../images/screenshot_1579269992927.png) 8. 理论上看,所有业务API,都需要进行鉴权,这样才能保证整个系统的安全性,但也有个别特例情况,API 不需要认证也可以调用,这里就需要用到 Secure 的 API 放行配置。 9. 有些业务 API 鉴权就算成功,也有可能需要根据角色权限来判断是否可以调用,这里就需要用到 Secure更细颗粒度的鉴权配置。 ## API 鉴权 ### 配置API放行 1. 若是使用SpringBoot版本,前往对应配置文件,增加接口放行配置 ![](../../images/screenshot_1579270170647.png) 2. 若是使用SpringCloud版本,则打开nacos,找到对应配置文件增加接口放行配置 ![](../../images/screenshot_1579270222602.png) 3. 若需要拦截某个api下所有的请求,则可以改为 `/api/**`, 其中 `**` 则代表下层所有请求 4. 重启工程,去掉请求头,可以看到,请求成功了,说明 `API 放行` 配置成功 ![](../../images/screenshot_1579270399594.png) ### 细颗粒度鉴权配置 1. 鉴权配置用到了 Secure 模块的 `@PreAuth` 注解 2. 为了可以起到对比的作用,对 `count` 进行权限放行(只要通过Token认证就可调用API)。 ~~~java @GetMapping("count") @PreAuth("permitAll()") public Integer count(Integer cnt) { return cnt * 10; } ~~~ 3. 对 `info`进行权限判断,调用方需要拥有`test`的角色权限才可以调用 ~~~java @GetMapping("info") @PreAuth("hasRole('test')") public String info(String name) { return "Hello, My Name Is: " + name; } ~~~ 4. 调用 `/api/count` 发现请求成功。 ![](../../images/screenshot_1579270526580.png) 5. 调用 `/api/info` 发现返回了 `请求未授权`,因为我们的`admin`账号没有分配`test`角色 ![](../../images/screenshot_1579270543657.png) 6. 尝试改回`admin`权限 ~~~java @GetMapping("info") @PreAuth("hasRole('administrator')") public String info(String name) { return "Hello, My Name Is: " + name; } ~~~ 7. 调用 `/api/info` 发现请求成功。 ![](../../images/screenshot_1579270606453.png) ## 结尾 * Secure 框架进行了两层 API 鉴权。 * 第一层校验请求携带的Token是否合法,不需要Token校验的可通过配置放行。 * 第二层校验`@PreAuth`配置的逻辑是否符合,若不符合也返回`请求未授权`。 * 注解 `@PreAuth`支持类层级和方法层级,放到类层级则对该类的所有方法进行鉴权。 * 注解 `@PreAuth`还支持 Spring el 表达式,可拓展性非常高,更多功能等您挖掘~ * Spring el 文档地址:[https://docs.spring.io/spring/docs/5.1.6.RELEASE/spring-framework-reference/core.html#expressions](https://docs.spring.io/spring/docs/5.1.6.RELEASE/spring-framework-reference/core.html#expressions)