## 简介 * Secure 基于 JWT 封装,每次请求的时候,会拦截到需要鉴权的API请求,并对其请求头携带的Token进行认证。 * 若 Token 过期、不存在、错误,都会导致鉴权失败,继而无法访问到对应的API。 * SpringBlade 的安全框架 Secure 在 [Blade-Tool](https://github.com/chillzhuang/blade-tool.git) 中,有兴趣的小伙伴可以阅读下源码,查看实现原理。 * 本章介绍 Secure 的基本使用方法。 ## 如何通过认证 1. 首先需要访问Auth接口,传入账号名密码,获得授权成功后的信息 2. 启动`AuthApplication`、`UserApplication`、 `BladeLogApplication`三个服务 ![](https://box.kancloud.cn/f929267260b15605e6eda440fab138ae_379x186.png) 3. 调用 http://localhost/blade-auth/token 传入对应参数,如下图所示则说明认证信息获取成功(**商业版的用户请查看OAuth2章节**) `("c3dvcmQ6c3dvcmRfc2VjcmV0"为clientId:clientSecret串转换为的base64编码,这个是可变的)` ![](https://box.kancloud.cn/4bf1a28dcd92a741ae1bc08ed9a99355_1786x438.png) ![](https://box.kancloud.cn/8559d4c47925e4b60483fabd6c3819f9_1784x1400.png) 4. 从返回的Json中取到 `tokenType` 和 `accessToken`,将他们拼接起来并以逗号隔开 5. 设置请求头为`blade-auth`,请求头对应的值为 `tokenType` + `' '` + `accessToken` (后续的所有接口调用都需要带上请求头为 `Authorization` 值为 `c3dvcmQ6c3dvcmRfc2VjcmV0`) 6. 再次调用 http://localhost/blade-demo/api/info?name=Chill 发现返回 `Hello, My Name Is: Chill` 说明鉴权成功! ![](https://box.kancloud.cn/725b745460b6b552ce51c5ddec5ce4cb_657x358.png) 7. 理论上看,所有业务API,都需要进行鉴权,这样才能保证整个系统的安全性,但也有个别特例情况,API 不需要认证也可以调用,这里就需要用到 Secure 的 API 放行配置。 8. 有些业务 API 鉴权就算成功,也有可能需要根据角色权限来判断是否可以调用,这里就需要用到 Secure更细颗粒度的鉴权配置。 <br> ## API 鉴权 ### 配置API放行 1. 若是使用SpringBoot版本,前往对应配置文件,增加接口放行配置 ![](https://img.kancloud.cn/3a/13/3a13cb714d3cee1adb8f3bb626cd804c_2430x1066.png) 2. 若是使用SpringCloud,则打开nacos,找到对应配置文件增加接口放行配置 ![](https://img.kancloud.cn/c8/6b/c86be25ea8a700259689faf716f86959_1780x1424.png) 3. 若需要拦截某个api下所有的请求,则可以改为 `/api/**`, 其中 `**` 则代表下层所有请求 4. 重启工程,去掉请求头,可以看到,请求成功了,说明 `API 放行` 配置成功 ![](https://box.kancloud.cn/8618457bee78709af09d2436c305f7e3_724x370.png) <br> ### 细颗粒度鉴权配置 1. 鉴权配置用到了 Secure 模块的 `@PreAuth` 注解 2. 为了可以起到对比的作用,对 `count` 进行权限放行(只要通过Token认证就可调用API)。 ~~~ @GetMapping("count") @PreAuth("permitAll()") public Integer count(Integer cnt) { return cnt * 10; } ~~~ 3. 对 `info`进行权限判断,调用方需要拥有`test`的角色权限才可以调用 ~~~ @GetMapping("info") @PreAuth("hasRole('test')") public String info(String name) { return "Hello, My Name Is: " + name; } ~~~ 4. 调用 `/api/count` 发现请求成功。 ![](https://box.kancloud.cn/a0b7f4eb4488b7c91962835e3d0b91eb_659x348.png) 5. 调用 `/api/info` 发现又变回了 `请求未授权`,因为我们的`admin`账号没有分配`test`角色 ![](https://box.kancloud.cn/8d796eae591cb83f64d327a4d781733e_701x412.png) 6. 尝试改回`admin`权限 ~~~ @GetMapping("info") @PreAuth("hasRole('administrator')") public String info(String name) { return "Hello, My Name Is: " + name; } ~~~ 7. 调用 `/api/info` 发现请求成功。 ![](https://box.kancloud.cn/0e9c601af49ebac007a05c0a3e2a2346_607x350.png) <br> ## 结尾 * Secure 框架进行了两层 API 鉴权。 * 第一层校验请求携带的Token是否合法,不需要Token校验的可通过配置放行。 * 第二层校验`@PreAuth`配置的逻辑是否符合,若不符合也返回`请求未授权`。 * 注解 `@PreAuth`支持类层级和方法层级,放到类层级则对该类的所有方法进行鉴权。 * 注解 `@PreAuth`还支持 Spring el 表达式,可拓展性非常高,更多功能等您挖掘~ * Spring el 文档地址:https://docs.spring.io/spring/docs/4.3.16.RELEASE/spring-framework-reference/htmlsingle/#expressions-operators-logical