SPEL expression permission control

Spring Expression expressions have been available since Spring Security 3.0 to control authorization, allowing complex Boolean logic to be used in expressions to control access permissions. The base class for the Spring Security available expression object is SecurityExpressionRoot.

Expression function describe
hasRole([role]) Returns true if the user has the specified role (Spring securityThe default isROLE_Prefix), remove prefix referencesRemove the ROLE$ITALICWORD
hasAnyRole([role1,role2]) Returns true if the user has any of the specified roles
hasAuthority([authority]) Returns true if you have access to a resource
hasAnyAuthority([auth1,auth2]) Returns true if you have access to parts of certain resources
permitAll Always return true
denyAll Always return false
anonymous The current user isanonymousReturns true when
rememberMe The current user isrememberMeUser returns true
authentication Of the current logged-in userauthenticationobject
fullAuthenticated The current user is neitheranonymousIs notrememberMeUser returns true
HasIpAddress (' 192.168.1.0/24 ')) Returns true if the sent IP addresses match

Some friends may be confused about Authority and Role. Authority Indicates the access permission of a button (for example, resource ID: biz1) or a user role (for example, resource ID: ADMIN). HasAuthority (‘ROLE_ADMIN’) has the same effect as hasRole (‘ADMIN’) when Authority is used as a role resource permission.

Use of SPEL in global configuration

We can through inheritance WebSecurityConfigurerAdapter, implement relevant configuration method, for the global security configuration (chapters have said before). Here’s how to use SPEL expressions in global configuration.

2.1.URL security expressions

config.antMatchers("/system/*").access("hasAuthority('ADMIN') or hasAuthority('USER')")
      .anyRequest().authenticated();Copy the code

Here we define the scope of the application /person/*URL so that only ADMIN or USER users can access these Person resources.

2.2. Reference beans in secure expressions

This approach is best suited for situations with complex permission validation logic, where the default expression method provided by Spring Security does not meet our needs. First we define an RbacService for permission validation.

Component("rbacService") @slf4j public class rbacService {// Return true to validate public Boolean HasPermission (HttpServletRequest Request, Authentication Authentication) {return true; } public Boolean checkUserId(Authentication Authentication, int id) {return true; }}Copy the code

For access to the resource corresponding to “/person/{id}”, the rbacService bean method checkUserId is used to verify the permission, passing the authentication object and the ID of the person. The ID is PathVariable and starts with #.

config.antMatchers("/person/{id}").access("@rbacService.checkUserId(authentication,#id)")
      .anyRequest().access("@rbacService.hasPermission(request,authentication)");Copy the code

Method expression security control

If we want to implement method-level Security configuration, Spring Security provides four annotations, which are @preauthorize, @prefilter, @postauthorize, and @postfilter

3.1. Enable the configuration of method level annotations

In the Spring security configuration code, plus EnableGlobalMethodSecurity annotations, opening method level security configuration function.

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MySecurityConfig extends WebSecurityConfigurerAdapter {Copy the code


3.2 Use PreAuthorize annotations

The @preauthorize annotation is appropriate for authorization validation before entering a method. You must have an ADMIN role to access the findAll method.

@PreAuthorize("hasRole('ADMIN')")
List<Person> findAll();Copy the code

3.3 Use PostAuthorize annotations

The @postauthorize authorization is executed after the method is executed. It is appropriate to validate the authorization based on the result of the returned value. Spring EL provides return objects that can be returnObject in the expression language. The following code returns an exception only if the name of the return value is equal to the name of the Authentication object.

@PostAuthorize("returnObject.name == authentication.name")
Person findOne(Integer id);Copy the code

3.4 Using PreFilter Annotations

PreFilter filters for parameters. The following code shows that the filter is for IDS parameters. Only ids with even ids can access the delete method.

@prefilter (filterTarget="ids", value="filterObject%2==0") public void delete(List<Integer> ids, List<String> usernames) {Copy the code

3.5 Using PostFilter Annotations

PostFilter filters the returned result, especially the return value of the collection class, and filters the objects in the collection that do not match the expression.

@PostFilter("filterObject.name == authentication.name")
List<Person> findAll();Copy the code

We look forward to your attention

  • The blogger has recently written a new book: “SpringBoot Series – Chapter 16, Verse 97.”
  • This article is reprinted with a credit (must be accompanied by a link, not only the text) : Antetokounmpo blog.