When I was working on the project in Qunar, I took over a particularly big demand: to transform the authority management of our trading background system.

background

At that time, the permission management of the background system was really a mess, including:

  • There are several roles specified by default, only one role can be configured on each user attribute, and what each role can do in the code is written to death (many systems do this in the early stage).
  • I’ve done a lot of campaigns, and almost every campaign’s administrator is written down individually and scattered around (hard-coded as we all do)
  • In addition to Qunar’s own administrators, the administrators from the suppliers use the backend. In the beginning, the authority of the supplier administrator is the same. In the later period, the supplier administrator also needs to support its own super administrator and ordinary administrator, and can also assign authority to its own people in its own shop
  • The project was originally written using servlets and later changed to SpringMVC, but many of the interfaces of the servlets were still used, resulting in a variety of interface names and classes providing external interfaces everywhere
  • The name of the interface is also various, the code can not distinguish between the background interface, which is the front interface

Design and development process

After careful research, I chose to write a new permission system. To explain why the popular Spring Security and Apache Shiro frameworks were not used, the background user logged in like this: First, go through the login process of Qunar website. When the login is successful, cookies will be placed in the specified domain, and then the background will parse cookies through the specified toolkit to obtain user information. This cannot be changed, which is inconsistent with the authentication mechanism and authorization process managed by the two frameworks themselves.

Next is the specific design and development, how step by step to sort out this mess

  • First, an independent and complete management function based on ROLE-bases Access Control (RBAC) model is required. Here, we also have a lot of administrator and background modules, so we need to expand the RBAC model: introduce departments in the upper layer of users and a layer of permission module in the upper layer of permission points, so that users and permission points can be viewed in a tree for easy use
  • Once you can assign permissions and users by role, you need to focus on how to make the original “permissions” compatible. First of all, it is compatible with several original role attributes in the system. New corresponding roles are added and corresponding permissions are assigned. Users previously configured with this role are bound to the ROLE of RBAC, so that the user completes the permission migration in the first layer of role attributes. The next step is the compatibility of activity permissions. Create an administrator for each activity, bind the user previously responsible for the activity to the corresponding role, and then configure and manage the corresponding activity permissions for these roles.
  • With an administrative model, and compatibility with the original data, the next step is to determine which interfaces to intercept. Because the interface is messy, how to determine which interface to intercept it, in the case of artificial class by class inspection is not realistic, write a script to the server of the background system, record the URL list that the background system is accessed, run for a few days can get most of the interface, individual leakage of the network, the basic is not the core.
  • The next step is to implement permission interception, get the current user and access URL, according to the RBAC model management data, determine whether there is permission to access. One complication is that many of the early Serlvet interfaces defined different interfaces with different parameters, such as: the product page request for sale is /product.do? Type =onsale, the page request is /product.do? Type =offline. For this reason, I support the detection of parameters in the permission separately. When the configured permission contains parameters, I read and query matching parameters one by one to find out the final verification permission point, indirectly realizing the processing of data permission.
  • Interface authority interception finished, considering that some of our back-end pages are JSP pages, JSP pages on many buttons can determine whether there is authority when rendering, there is authority to display, so the development of a set of tags to do authority verification. Use labels to wrap the buttons that need to determine permissions, and pass in the corresponding unique permission identifier. When the page loads, the buttons without permissions will not be displayed. When separating the front and back ends in the later stage, the display of these buttons on the page is determined by calling the interface first, which is not displayed by default. The interface returns that it has permission to display the buttons again.
  • Permission interception is not complete here, because each check will involve multiple table query operations, which will add a lot of access to the database, and the user’s permissions themselves change very rarely, so many points of permission interception need to be cached

Implementation process

After these are done, how to ensure safety on the line? It was released several times, step by step

  • First, go live with all the administrative functions of the RBAC model, then configure the required roles and cut off only one small function to intercept administration using the new authority framework
  • For the second time, the new permission framework is used to manage all the background functions of Qunar administrator. The workload of this configuration is large, almost all the URLS of the background should be configured again, and the allocation should be done
  • For the third time, a new authority framework was used to manage the management function of the vendor side. This time, it was risky and was released in the early morning when everyone was sleeping. At that time, considering that many suppliers might not know how to assign permissions under their own shops to the pages provided by them, I prepared teaching PPT for operation and maintenance side. In the development side, I specially added the function that I could enter the shop as a super administrator to assist in maintenance.
  • The fourth time, online a special function: according to the login user has assigned permissions, the generation of multi-level menu background. Is the premise of the different types of access point of the menu and button, at the same time for each module is only one menu below, ensure that the access module and the management of the access point is corresponding to the menu item and menu management under the page, so according to the user distribution menu permissions, calculate the tree structure composed of access modules and access point, The front end then uses JSTL rendering on the JSP page. At this point, the whole permission switch came to an end.

subsequent

After the project has also been on some practical tools, these tools are applicable to most of the authority system, including: Query specifies the user has assigned the role of, query specifies the user’s current have permissions, query designated authority by which roles have specified permissions, query by which a user has, etc., these features can greatly convenient access administrator to access data for maintenance, it also supports the dynamic refresh the cache user permissions, After the user rights are modified, the user rights take effect in real time. One feature that is missing but worth mentioning is the ability to restore a certain operation of the administrator, which can roll back permission data in a timely manner after malicious or incorrect operation.

Of course, this authority system can support many extensions, such as: the department to add the concept of a supervisor, the supervisor has the following employee authority total; You can assign permissions not only to users but also to departments. All users in departments have the permissions assigned by departments. When the department hierarchy has real meaning, permissions are inherited and so on. These can be scaled up as the business gets more complex, but not yet.

In addition, this authority system also does not want to manage one side, the most important is horizontal overreach. Horizontal overreach itself is closely related to business. For example, a supplier administrator wants to operate a product and then wants to check whether the product belongs to the supplier, so he needs to obtain the product ID. In this case, you may encounter, The parameters of the product id may be productId, productId, id, pId, and so on one of the (different developers to define the parameter name is different), very not easy to get the parameters, you will also find that sometimes this value is the product id, sometimes is the encrypted value. When you finally get this done, the business changes and a new business form emerges: one big supplier has multiple small suppliers, and their products can be shared… Say these, mainly want to explain a point, horizontal overreach is best handed over to the business layer to do, placed in the authority can do, but may be excluded from some business, at the same time, if done in the authority management, then the subsequent interface should comply with some specifications.

At the end

During the transformation of the permission system, I exported a large number of wikis to introduce the reformed permission framework, but it was still difficult for the members of the group to complete the permission configuration independently. Therefore, I shared the new permission management for four times, covering the technologies involved, algorithms and details of use. Finally get a title: authority emperor.

(after)