background
Friends who have transformed from traditional monolithic applications to Spring Cloud are asking me, how to manage the microservice permissions under Spring Cloud ? How to design more reasonably? From a large perspective, it is called service permissions, which are divided into three parts:用户认证,用户权限, and服务校验.
User Authentication
Traditional monolithic applications may be accustomed to the existence of sessions. After Spring cloud's microservices, sessions can be solved by distributed sessions, but they are not the best strategy after all. Some people started to implement Spring Cloud Security combined with OAuth2 , which is well-known for its OAuth2. Later, in order to optimize the storage problems of Access Token in OAuth 2 and improve the availability and scalability of back-end services, there is a better token verification method JWT (JSON Web Token). One thing to emphasize here is that OAuth2 and JWT are not comparable at all, they are two completely different things.
OAuth2是一种授权框架, while JWT is an authentication protocol
OAuth2 authentication framework OAuth2 contains four roles:
OAuth2 contains 4 authorization modes
Among them, the operation process of OAuth2 is shown in the figure below, excerpted from RFC 6749:
+--------+ +------------------------+| |--(A)- Authorization Request ->| Resource || | | | | Owner || |<-(B)-- Authorization Grant ---| || | +------------------------+| || | +-------------------+| |--(C)-- Authorization Grant -->| Authorization || Client | | | Server || |<-(D)--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----->| Resource || | | Server ||<-(F)--- Protected Resource ---| |+--------+ +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
In Spring Cloud OAuth2, all requests to access microservice resources carry tokens in the Http Header. The accessed service will then request the authorization server to verify the validity of the token. In this way, we need两次或者更多次requests. All token validity verification falls on the authorization server, which has become a very big bottleneck for the horizontal expansion of our system.
JWT certification protocol
授权服务器serializes user information and authorization scope and puts a JSON string, then uses Base64 to encode it, and finally signs the string with a private key in the authorization server to obtain a JSON Web Token .
Assuming that all other resource servers will hold an RSA public key. When the resource server receives the request to have a token in the Http Header, the resource server can get the token and verify whether it uses the correct private key signature (whether it has been signed by the authorized server, that is, signature verification). After passing the verification, the valid verification information contained in Toekn will be obtained after deserialization.
Among them, the main operation flowchart is as follows:
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Through the above method, we can complete the service-based user authentication well.
User permissions
Everyone likes shiro for permission blocking of traditional single-body applications, and it is quite easy to use. But once split, the permissions begin to be scattered across the various APIs. Is shiro still working? In the project, I did not use shiro . After the front and back ends are separated, the interaction is token, the backend services are stateless, the front-end buttons are resourced, and where can we manage the permissions?
Abstract and design
Before introducing flexible core design, let me introduce a preview concept to you: RBAC (Role-Based Access Control, role-based access control), which means that users associate with permissions through roles. Simply put, a user has several roles, and each role has several permissions.
RBAC is actually an analytical model, mainly divided into: basic model RBAC0 (Core RBAC), role hierarchal model RBAC1 (Hierarchal RBAC), role restriction model RBAC2 (Constraint RBAC) and unified model RBAC3 (Combines RBAC).
Core UML
This is the author's abstract RBAC relationship diagram after multiple 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 the user, groups or groups of different business scenarios are formed, and users' permissions are obtained through authorization to the parent class of the group or group.
Permission
Permissions, integration with a certain number of resources, can also be the carrier of resources.
Resources
There are resources under permissions, and the sources of resources include: Menu (menu), Button (action permission), page elements (button, tab, etc.), data permissions, etc.
Program
Programs, the rendering carrier for related permission controls, can be mounted in multiple menus.
Basic composition of common web programs
The relationship between model and microservices
If all API interfaces after Spring Cloud service are defined as Resources above, then we can see such a situation.
For example, if a user adds, deletes, modifys and checks, our page will do this.
| Page elements | Resource encoding | Resource URI | Resource request method |
|---|---|---|---|
| Query | user_btn_get | /api/user/{id} | GET |
| Increase | user_btn_add | /api/user | POST |
| edit | user_btn_edit | /api/user/{id} | PUT |
| delete | user_btn_del | /api/user/{id} | DELETE |
After abstracting into the above mapping relationship, our front and back end resources are referenced, making it easier for us to authorize the user group permissions. For example, I grant a user permission to add and delete. In前端we only need to verify whether the资源编码exists or not to control the display and hiding of the buttons, while in后端, we only need to uniformly intercept and determine whether the user has URI and corresponding请求方式.
As for whether the unified permission interception is placed on the Zuul gateway or placed on the interceptor of the specific backend service (Filter, Inteceptor), it can be easily implemented. Not limited to invasiveness of the code. The flowchart of placing Zuul is as follows:
If the unified interception of permissions is placed on Zuul , there will be a problem, that is, whether the back-end service is secure, and the service only needs to be called through the registration center. This involves the third module behind, authentication between services.
Authentication between services
Because we all know that services are directly called remote procedures after they find the client through the registration center. We need to protect each service and sensitive interface in production. The process of the topic is as follows:
The author's implementation method is based on Spring Cloud's FeignClient Inteceprot (automatically apply for service token, pass the current context) and Mvc Inteceptor (service token verification, update the current context) to further protect the security of the service.
After combining the features of Spring Cloud, the overall flow chart is as follows:
Optimization point
Although the security of the API interface is ensured through the above-mentioned user legality verification, user permission interception and authentication between services, Http访问频率is relatively high. When the number of requests increases, the problem of慢will be particularly obvious. Certain optimization strategies can be considered, such as user permission cache, distribution and mixed storage of service authorization information, and regular refresh of service authentication tokens.
Conclusion
The above is my general idea in the project. Interested friends can learn from my open source project. Welcome to star:
- gitchina: https://gitee.com/minull/ace-security (Jwt, user permissions)
- github: https://github.com/wxiaoqi/ace-security
- gitchina: http://git.oschina.net/geek_qi/ace-gate (service authentication)
The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.