Background management system -- Design and implementation of row authority and column authority

Opening note

  • If you have been inspired and thought here, I hope you can praise and support! You have different views on the content. Welcome to write and exchange.
  • Technology stack > > java
  • Mailbox > > 15673219519@163.com

describe

  • In the background system, in addition to assigning different menus according to roles, it is often encountered that different roles or different personnel have different query and selection permissions in one menu.
  • Query authority can be divided into row query and column query. The implementation of row query is relatively simple. The following will briefly list the methods I have encountered; However, column permissions do not seem to see a good implementation method, and the implementation is more complex, so there is no way to start.
  • Next, I will describe my implementation in the system. Including row permissions and column permissions.

My thoughts

  • Row permissions
    • 1. Generally, you can filter out the data that roles or users do not have permission to query through filters or AOP. (recommended)
    • 2. You can also restrict you to fill in only authorized search criteria in search addition. (not recommended, this method can be bypassed)
  • Column permission
    • 1. When there are many kinds of role permissions, we can realize the column permission function by recording the columns owned by each role on each page and the operable functions in the database. (recommended)
    • 2 when there are few types of role permissions to distinguish, you can write different pages for different roles. This method is only suitable for the situation with few roles, otherwise the development and maintenance cost is too high. (not recommended)

Line permissions (provide implementation ideas, and the specific details need to be based on the actual situation of different projects)

  • Implementation goal: for queries involving row permissions, you can filter out data without permissions as long as you add a custom annotation @ SearchPermissions. As follows:
@SearchPermissions
@PostMapping("/get/page")
public MSG<PageInfo<User>> getListForPage(@RequestBody UserSearchDto searchDto){
    // TODO
    return MSG.SUCCESS();
}
  • Create custom annotation
    SearchPermissions.java
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SearchPermissions {
}

SearchPermissionsAspect.java

@Slf4j
@Aspect
@Component
public class SearchPermissionsAspect {

    @Pointcut("@annotation(com.qykj.admin.aspect.SearchPermissions)")
    public void pointcut() {}

    @Before("pointcut()")
    public void process(JoinPoint point){
        // 1. TODO obtains the currently requested user role through the request and queries its query permissions
        
        // 2. TODO obtains user query conditions through point. Generally, it encapsulates relevant query fields related to permission control into a public base class for easy operation here
        
        // 3. Filter out the query criteria that the user does not have
        }
    }
}

Column permissions (provide implementation ideas, and the specific details need to be based on the actual situation of different projects)

  • Achieve the goal: the related involved need column permissions. For the query of operation permissions, just add the custom annotation @ FieldFilter(javaType = User.class, name = "user_list@view ") can filter out data without permission. As follows:
@SearchPermissions
@FieldFilter(javaType = UserParent.class, name="name = "user_list@view")
@PostMapping("/get/page")
public MSG<PageInfo<User>> getListForPage(@RequestBody UserSearchDto searchDto){
    // TODO
    return MSG.SUCCESS(listForPage);
}
  • Create custom annotation
    FieldFilter.java
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FieldFilter {
    
    // The class User.class to be filtered filters out the fields in the User class
    Class javaType() default Object.class;
    
    // This is used to identify whether the request controls the column permission or operation permission (user) of the page_ list@view User list column permissions), (user_list@opt User list (operation permission)
    String name() default "";
}
@Aspect
@Component
public class FieldFilterAspect {

    @Pointcut("@annotation(com.qykj.admin.aspect.FieldFilter)")
    public void fieldFilterAspect(){}
    
    @Around("fieldFilterAspect()")
    public MSG around(JoinPoint point) throws Throwable {
        // 1. TODO obtains the user role ID of the current request through the request
        
        // 2. TODO obtains the controller method @ fieldfilter (javatype = user. Class, name = "user") through point_ list@view "), you can know the operation of that page
        
        // 3. TODO passes user_list@view +The role ID can be obtained from the database, and the fields and operation permissions can be returned
        
        // 4. When TODO is serialized through JSON, only fields with permission can be serialized
        
        return MSG;
    }
}

summary

  • user_list@view Medium user_ The menu view ID of the page corresponding to list is the query column. These can be completely customized, and can be realized mainly by implementing the ideas and steps in TODO.
  • In this example, column permissions are mainly realized by using JSON serialization, which dynamically serializes only the fields with permissions. You also need front-end cooperation to render the form according to the fields you return. In order to ensure that the front end can correctly render the header when the query is empty, the back end needs to provide an interface to identify which fields to query according to the menu.

Tags: Java AOP filter

Posted on Tue, 30 Nov 2021 16:39:38 -0500 by SueHubert