Skip to content

5.3.1 Securing requests

You need to ensure that requests for /design and /orders are available only to authenticated users; all other requests should be permitted for all users. The following configuration does exactly that:

java
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
  return http
    .authorizeRequests()
      .antMatchers("/design", "/orders").hasRole("USER")
      .antMatchers("/", "/**").permitAll()

  .and()
  .build();
}

The call to authorizeRequests() returns an object (ExpressionUrlAuthorizationConfigurer.ExpressionInterceptUrlRegistry) on which you can specify URL paths and patterns and the security requirements for those paths. In this case, you specify the following two security rules:

  • Requests for /design and /orders should be for users with a granted authority of ROLE_USER. Don’t include the ROLE_ prefix on roles passed to hasRole(); it will be assumed by hasRole().
  • All requests should be permitted to all users.

The order of these rules is important. Security rules declared first take precedence over those declared lower down. If you were to swap the order of those two security rules, all requests would have permitAll() applied to them; the rule for /design and /orders requests would have no effect.

The hasRole() and permitAll() methods are just a couple of the methods for declaring security requirements for request paths. Table 5.1 describes all the available methods.

Table 5.1 Configuration methods to define how a path is to be secured

MethodWhat it does
access(String)Allows access if the given Spring Expression Language (SpEL) expression evaluates to true
anonymous()Allows access to anonymous users
authenticated()Allows access to authenticated users
denyAll()Denies access unconditionally
fullyAuthenticated()Allows access if the user is fully authenticated (not remembered)
hasAnyAuthority(String...)Allows access if the user has any of the given authorities
hasAnyRole(String...)Allows access if the user has any of the given roles
hasAuthority(String)Allows access if the user has the given authority
hasIpAddress(String)Allows access if the request comes from the given IP address
hasRole(String)Allows access if the user has the given role
not()Negates the effect of any of the other access methods
permitAll()Allows access unconditionally
rememberMe()Allows access for users who are authenticated via remember-me

Most of the methods in table 5.1 provide essential security rules for request handling, but they’re self-limiting, enabling security rules only as defined by those methods. Alternatively, you can use the access() method to provide a SpEL expression to declare richer security rules. Spring Security extends SpEL to include several securityspecific values and functions, as listed in table 5.2.

Table 5.2 Spring Security extensions to the Spring Expression Language

Security expressionWhat it evaluates to
authenticationThe user's authentication object
denyAllAlways evaluates to false
hasAnyAuthority(String… authorities)true if the user has been granted any of the given authorities
hasAnyRole(list of roles)true if the user has any of the given roles
hasAuthority(String authority)true if the user has been granted the specified authority
hasPermission(Object target, Object permission)true if the user has access to the specified target object for the given permission
hasPermission(Object target, String targetType, Object permission)true if the user has access to the object specified by targetId and the specified targetType for the given permission
hasRole(role)true if the user has the given role
hasIpAddress(IP Address)true if the request comes from the given IP address
isAnonymous()true if the user is anonymous
isAuthenticated()true if the user is authenticated
isFullyAuthenticated()true if the user is fully authenticated (not authenticated with remember-me)
isRememberMe()true if the user is authenticated via remember-me
permitAll()Always evaluates to true
principalThe user's principal object

As you can see, most of the security expression extensions in table 5.2 correspond to similar methods in table 5.1. In fact, using the access() method along with the hasRole() and permitAll expressions, you can rewrite the SecurityFilterChain configuration as follows.

Listing 5.7 Using Spring expressions to define authorization rules

java
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
  return http
    .authorizeRequests()
      .antMatchers("/design", "/orders").access("hasRole('USER')")
      .antMatchers("/", "/**").access("permitAll()")

    .and()
    .build();
}

This may not seem like a big deal at first. After all, these expressions only mirror what you already did with method calls. But expressions can be much more flexible. For instance, suppose that (for some crazy reason) you wanted to allow only users with ROLE_USER authority to create new tacos on Tuesdays (for example, on Taco Tuesday); you could rewrite the expression as shown in this modified version of the SecurityFilterChain bean method:

java
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
  return http
    .authorizeRequests()
      .antMatchers("/design", "/orders")
        .access("hasRole('USER') && " +
          "T(java.util.Calendar).getInstance().get("+
          "T(java.util.Calendar).DAY_OF_WEEK) == " +
          "T(java.util.Calendar).TUESDAY")
      .antMatchers("/", "/**").access("permitAll")

    .and()
    .build();
}

With SpEL security constraints, the possibilities are virtually endless. I’ll bet that you’re already dreaming up interesting security constraints based on SpEL.

The authorization needs for the Taco Cloud application are met by the simple use of access() and the SpEL expressions. Now let’s see about customizing the login page to fit the look of the Taco Cloud application.

Released under the MIT License.