Microservice authorization

background

Friends who have transformed from traditional monolithic applications to Spring Cloud are asking me, Spring Cloudhow to manage the permissions of microservices? How to design more reasonable? From a large level, it is called service authority, and it is divided into three parts: 用户认证, 用户权限, and 服务校验.

User Authentication

Traditional monolithic applications may be accustomed to the existence of sessions, but after Spring Cloud's microservices, although sessions can be solved by distributed sessions, it is not the best policy after all. Some people started to implement Spring Cloud Security very well OAuth2. Later, in order to optimize the storage problem in OAuth 2 Access Tokenand improve the availability and scalability of back-end services, there was a better token verification method JWT(JSON Web Token). The point to be emphasized here is that there is no comparison  OAuth2with these two at all, they are two completely different things. , but an authentication protocolJWT
OAuth2是一种授权框架JWT

OAuth2 Authentication Framework

There are four roles included in OAuth2:
  • Resource Owner
  • Resource Server
  • Authorization Server
  • Client (Client)
OAuth2 includes 4 authorization modes
  • Authorization code (Authorization code)
  • Simplified (Invisible) Mode
  • Username Password Mode (Resource Owner Password Credential)
  • Client Credential

Among them, the operation process of OAuth2 is as follows, which is taken from RFC 6749:

 

+--------+                               +---------------+
|        |--(A)- Authorization Request ->|   Resource    |
|        |                               |     Owner     |
|        |<-(B)-- Authorization Grant ---|               |
|        |                               +---------------+
|        |
|        |                               +---------------+
|        |--(C)-- Authorization Grant -->| Authorization |
| Client |                               |     Server    |
|        |<-(D)----- Access Token -------|               |
|        |                               +---------------+
|        |
|        |                               +---------------+
|        |--(E)----- Access Token ------>|    Resource   |
|        |                               |     Server    |
|        |<-(F)--- Protected Resource ---|               |
+--------+                               +---------------+

 

我们在Spring Cloud OAuth2中,所有访问微服务资源的请求都在Http Header中携带Token,被访问的服务接下来再去请求授权服务器验证Token的有效性,目前这种方式,我们需要两次或者更多次的请求,所有的Token有效性校验都落在的授权服务器上,对于我们系统的水平扩展成为一个非常大的瓶颈。

JWT认证协议

授权服务器将用户信息和授权范围序列化后放入一个JSON字符串,然后使用Base64进行编码,最终在授权服务器用私钥对这个字符串进行签名,得到一个JSON Web Token

假设其他所有的资源服务器都将持有一个RSA公钥,当资源服务器接收到这个在Http Header中存有Token的请求,资源服务器就可以拿到这个Token,并验证它是否使用正确的私钥签名(是否经过授权服务器签名,也就是验签)。验签通过,反序列化后就拿到Toekn中包含的有效验证信息。

其中,主体运作流程图如下:

+-----------+                                     +-------------+
|           |       1-Request Authorization       |             |
|           |------------------------------------>|             |
|           |     grant_type&username&password    |             |--+
|           |                                     |Authorization|  | 2-Gen
|           |                                     |Service      |  |   JWT
|           |       3-Response Authorization      |             |<-+
|           |<------------------------------------| Private Key |
|           |    access_token / refresh_token     |             |
|           |    token_type / expire_in           |             |
|  Client   |                                     +-------------+
|           |                                 
|           |                                     +-------------+
|           |       4-Request Resource            |             |
|           |-----------------------------------> |             |
|           | Authorization: bearer Access Token  |             |--+
|           |                                     | Resource    |  | 5-Verify
|           |                                     | Service     |  |  Token
|           |       6-Response Resource           |             |<-+
|           |<----------------------------------- | Public Key  |
+-----------+                                     +-------------+

通过上述的方式,我们可以很好地完成服务化后的用户认证。

用户权限

传统的单体应用的权限拦截,大家都喜欢shiro,而且用的颇为顺手。可是一旦拆分后,这权限开始分散在各个API了,shiro还好使吗?笔者在项目中,并没有用shiro。前后端分离后,交互都是token,后端的服务无状态化,前端按钮资源化,权限放哪儿管好使?

抽象与设计

在介绍灵活的核心设计前,先给大家普及一个入门的概念:RBAC(Role-Based Access Control,基于角色的访问控制),就是用户通过角色与权限进行关联。简单地说,一个用户拥有若干角色,每一个角色拥有若干权限。

RBAC is actually an analysis model, which is mainly divided into: basic model RBAC0 (Core RBAC), role hierarchical model RBAC1 (Hierarchal RBAC), role restriction model RBAC2 (Constraint RBAC) and unified model RBAC3 (Combines RBAC).

For more details, you can learn: RBAC Permission Model

 

Core UML



 This is the author's abstract RBAC relationship diagram after passing through various business scenarios

class description
  • Group

A group or group, a collection with a certain number of permissions, can also be a carrier of permissions.

子类: User (user), Role (role), Position (post), Unit (department), through the specific composition of users, groups or groups of different business scenarios are formed, and through the authorization of the parent class of the group or group, the user is completed. access to permissions.

  • Permission

Permissions, the integration of a certain number of resources, can also be the carrier of resources.

  • Resources

There are resources under permissions. The sources of resources are: Menu (menu), Button (action permissions), page elements (buttons, tabs, etc.), data permissions, etc.

  • Program

The program, the presentation carrier of the relevant permission control, can be mounted in multiple menus.

  • Basic composition of common web programs


  •  
    The relationship between models and microservices

    If all the api interfaces after Spring Cloud service are defined as above Resources, then we can see such a situation.

    For example, a user's additions, deletions, changes, and checks, our page will do this 



 

Page Element Resource Code Resource URI Resource Request Method
查询 user_btn_get /api/user/{id} GET
增加 user_btn_add /api/user POST
编辑 user_btn_edit /api/user/{id} PUT
删除 user_btn_del /api/user/{id} DELETE

在抽象成上述的映射关系后,我们的前后端的资源有了参照,我们对于用户组的权限授权就容易了。比如我授予一个用户增加、删除权限。在前端我们只需要检验该资源编码的有无就可以控制按钮的显示和隐藏,而在后端我们只需要统一拦截判断该用户是否具有URI和对应请求方式即可。

至于权限的统一拦截是放置在Zuul这个网关上,还是落在具体的后端服务的拦截器上(Filter、Inteceptor),都可以轻而易举地实现。不在局限于代码的侵入性。放置Zuul流程图如下: 



 要是权限的统一拦截放置在Zuul上,会有一个问题,那就是后端服务安不安全,服务只需要通过注册中心,即可对其他服务进行调用。这里就涉及到后面的第三个模块,服务之间的鉴权。

服务之间的鉴权

因为我们都知道服务之间开源通过注册中心寻到客户端后,直接远程过程调用的。对于生产上的各个服务,一个个敏感性的接口,我们更是需要加以保护。主题的流程如下图: 

 



 笔者的实现方式是基于Spring Cloud的FeignClient Inteceprot(自动申请服务token、传递当前上下文)和Mvc Inteceptor(服务token校验、更新当前上下文)来实现,从而对服务的安全性做进一步保护。

结合Spring Cloud的特性后,整体流程图如下: 



 

优化点

虽然通过上述的用户合法性检验、用户权限拦截以及服务之间的鉴权,保证了Api接口的安全性,但是其间的Http访问频率是比较高的,请求数量上来的时候,的问题是就会特别明显。可以考虑一定的优化策略,比如用户权限缓存、服务授权信息的派发与混存、定时刷新服务鉴权Token等。

 

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326349971&siteId=291194637