Step-by-step learning of spring security Chapter 13 What are the four kinds of authority controls? How to use the case in the project

review

Previously, we have passed the seventh chapter of "Study spring security step by step, how to configure permissions based on user table and permission table?" The more you learn, the easier it is to introduce how to dynamically authorize users and control URL permissions, and then through " Step by Step Learning Spring Security Chapter 11 How to Dynamically Control URLs?" How to dynamically add permissions to users? "Introduced how to dynamically assign URL permissions and user permissions. Today, we continue to introduce the four modes of permissions

  • Expressions to control URL path permissions
  • Expression Control Method Permissions
  • Use filter annotations
  • dynamic permissions

four modes

Expressions to control URL path permissions

In fact, it is to control the URL path authority through expressions. This method has actually been mentioned in the previous article, and here we will review it a little bit.

Spring Security supports the use of SpEL expressions in URL and method permission control. If the return value of the expression is true, it means that the corresponding permission is required, otherwise it means that the corresponding permission is not required. The class that provides the expression is SecurityExpressionRoot:

insert image description here
It can be seen that SecurityExpressionRoot has two implementation classes, which represent the expansion of SpEL when dealing with URL authority control and method authority control. For example, when doing authority control based on URL path, the hasIpAddress option is added.

Let's take a look at the most basic SpELs defined in the SecurityExpressionRoot class:
insert image description here
As you can see, these are expressions corresponding to this class. I have listed these expressions in tables to illustrate their functions.

expression Remark
hasRole Have the specified role to access resource permissions
hasAnyRole Access resources with any of several roles
hasAuthority Similar to hasRole
hasAnyAuthority Similar to hasAnyRole
permitAll All allowed
denyAll Total Deny Access
isAnonymous Determine whether an anonymous user
isAuthenticated Determine whether the authentication is successful
isRememberMe Determine whether to remember me logged in
isFullyAuthenticated Determine whether the username/password is logged in
principle Current user
authentication User object extracted from SecurityContext

Listed here are the most basic and commonly used methods

If the permission control is performed through the URL, then we only need to configure it as follows:

@Override
    protected void configure(HttpSecurity http) throws Exception {
    
    
        http.authorizeRequests()
                .antMatchers("/admin/**").hasRole("admin")
                .antMatchers("/user/**").hasRole("user")
                .anyRequest().authenticated()
             ;
    }

here means visit

  • Paths in the format /admin/** require the admin role
  • Accessing paths in the /user/** format requires the user role

This is static configuration. When you need to determine in advance which URLs have what permissions to access, you can configure it in this way, but this way of configuration has a disadvantage, that is, every time you add an interface permission, you will get it in the configuration file. To configure permissions, that is, you need to modify the original code, which is easy to cause bugs. Therefore, in development, it is generally not configured in this way

Expression Control Method Permissions

Of course, we can also control permissions by adding annotations to methods. We need to first enable the use of the annotation @EnableGlobalMethodSecurity, and add the following content to the Spring Security configuration class:

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true,securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
    
    ...
    ...
}

This configuration enables three annotations, namely:

annotation Remark
@PreAuthorize Permission check before method execution
@PostAuthorize Permission check after method execution
@Secured Similar to @PreAuthorize

After these three are combined with SpEL, the usage is very flexible. Here are a few demos to share with you.

  /**
     *  @PreAuthorize("principal.username.equals('mike')") 注解的约束是,只有当前登录用户名为 mike 的用户才可以访问该方法。
     * @return
     */
    @PreAuthorize("principal.username.equals('mike')")
    @RequestMapping("/hello")
    public String hello(){
    
    
        return "一望二三里----某某诗人,hello user: "+getLoginUser();
    }

    /**
     *  @PreAuthorize("hasRole('admin')") 表示访问该方法的用户必须具备 admin 角色。
     * @return
     */
    @RequestMapping("/admin/index")
    @PreAuthorize("hasRole('admin')")
    public String adminIndex(){
    
    
        return "落霞与孤鹜齐飞,秋水共长天一色----某某诗人,hello user: "+getLoginUser();
    }

    /**
     * @Secured({"ROLE_user"})表示方法该方法的用户必须具备 user 角色,但是注意 user 角色需要加上 ROLE_ 前缀。
     * @return
     */
    @RequestMapping("/user/index")
    @Secured({
    
    "ROLE_user"})
    public String userIndex(){
    
    
        return "采菊东篱下悠然见南山----陶渊明,hello user: "+getLoginUser();
    }

    /**
     * 访问该接口的 score 参数必须大于 80,否则请求不予通过。
     * @return
     */
    @RequestMapping("/score")
    @PreAuthorize("#score>80")
    public String getScore(int score){
    
    
        return "当前登录用户"+getLoginUser()+"查询成绩:"+score;
    }
  • For the first /hello interface, the constraint of the annotation is that only the user who is currently logged in as mike can access this method.
  • The second /admin/index interface means that users who access this method must have the admin role.
  • The third /user/index interface indicates that the user of this method must have the user role, but note that the user role needs to be prefixed with ROLE_.
  • The fourth /score interface means that the score parameter of accessing this method must be greater than 80, otherwise the request will not be passed.

The expressions here are still very rich. If you want to refer to the parameters of the method, just add a # in front of it. You can refer to parameters of basic types or object parameters.
In addition to principal, the default object also has authentication

In fact, these annotation expressions can be used not only on the controller interface, but also on services, or other spring-managed bean methods.
Obviously, using expressions to control method permissions is suitable for our development, why? For example, I need to add a controller interface now, and I need to control URL permissions for certain methods. I don’t need to modify the configuration, add a URL and specify permissions, just add a comment to the method of my controller, Such as @PreAuthorize("hasRole('admin')") where admin is the authority that should be controlled by the corresponding URL, and this is done. The advantage of this is that there is no need to modify the existing code, so as to better avoid the occurrence of bugs

Use filter annotations

There are also two filter functions @PreFilter and @PostFilter in Spring Security, which can automatically remove elements in the collection according to the given conditions.

    @RequestMapping("/getAllStudentScore")
    @PostFilter("filterObject>5")
    public List<Integer> getAllStudentScore() {
    
    
        List<Integer> users = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
    
    
            users.add(i);
        }
        return users;
    }

    @RequestMapping("/getAllAge")
    // @PreFilter("filterObject%2==0")
    @PreFilter(filterTarget = "ages",value = "filterObject%2==0")
    public List<Integer> getAllAge(@RequestBody List<Integer> ages) {
    
    
        System.out.println("ages = " + ages);
        return ages;
    }
  • In the getAllStudentScore interface, filter the collection and only return elements with a score greater than 5, and filterObject represents the element object to be filtered.
  • In the getAllAge method, if there is only one collection parameter, you don’t need to specify filterTarget to specify the filter object. If there are multiple parameters, you need to specify

Of course, these annotations can be used not only on the interface, but also on other spring-managed beans. Filtering annotations are very flexible and easy to develop. When expanding the original interface, it is tried and tested.

In the past, I wanted to return the data that met the conditions after filtering the data before a certain method returned the data, and filter out the unsatisfied data. How do I do it?
Because I don't want to modify the original code, because the code is not necessarily written by me, the logic is very complicated, changing other people's code or even my own code is easy to cause bugs, and then I will write an AOP to expand, the method After the data is returned, it is very painful to traverse to filter the data that meets the conditions, and then return. It is also very painful to create a new AOP to process each time, because it also needs to write a bunch of filtering logic

So what to do now?
You can change the original code, but how to change it this time? Just add an annotation @PostFilter on the method gently, and then write the filter conditions, that's it, isn't it much cooler?
Some people may say, isn't this going to change the original code? This is true, but if you look carefully, you will find that I just added a comment without modifying the original business logic, and it will not cause other bugs. This cost is still very small

dynamic permissions

In fact, we have learned spring security step-by-step in Chapter 11. How to dynamically control URLs? How to dynamically add permissions to users? "Dynamic permissions have been introduced. If you haven't read my previous article, you can go and read it first.

Well, through this article, do you know more about the rights management of spring security? If the knowledge of this article is comprehended, it will help you a lot about permission control during the development process, and it can also improve your development efficiency to a higher level.

The code involved in this article, I was in the previous " Step-by-Step Learning Spring Security Chapter 11 How to Dynamically Control URLs?" How to dynamically add permissions to users? "Written on the basis of the project, I will upload the code to the git warehouse later, you can download it and experience it, the download address can be downloaded from the previous article

Guess you like

Origin blog.csdn.net/huangxuanheng/article/details/119482277