Spring Security Expressions – hasRole Example

1. Overview

Spring Security provides a large variety of Expressions, using the powerful Spring Expression Language (SpEL). Most of these security expressions are evaluated against a contextual object – the currently authenticated principal.

The evaluation of these expressions is performed by the SecurityExpressionRoot – which provides the basis for both web security as well as method level security.

The ability to use SpEL expressions as an authorization mechanism was introduced in Spring Security 3.0 and is continued in Spring Security 4.x. For the comprehensive list of expressions in Spring Security, have a look at this guide.

Further reading:

Spring Security with Thymeleaf

A quick guide to integrating Spring Security and Thymeleaf

Read more

Introduction to Spring Method Security

A guide to method-level security using the Spring Security framework.

Read more

Two Factor Auth with Spring Security

A practical two-factor authentication implementation with Spring Security 4 and the Google Authenticator mobile app.

Read more

2. Web Authorization

Spring Security provides two types of web authorization – securing a full page based on the URL and conditionally showing parts of a JSP page based on security rules.

2.1. Full Page Authorization Example

With expressions enabled for the http element, an URL pattern can be secured as follows:

<http use-expressions = "true">
    <intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')" />
    ...
</http>

Using Java configuration:

@Configuration
@EnableWebSecurity
public class SecSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
          .authorizeRequests()
          .antMatchers("/admin/**").hasRole("ADMIN");
    }
    ...
}

Spring Security automatically prefixes any role with ROLE_.

The hasRole expression is used here to check if the currently authenticated principal has the specified authority.

2.2. In Page Authorization Example

The second kind of web authorization is conditionally showing some part of a JSP page based on the evaluation of a security expression.

Let’s add the required dependency for the Spring Security JSP taglib support in pom.xml:

<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-taglibs</artifactId>
    <version>5.0.5.RELEASE</version>
</dependency>

The taglib support has to be enabled on the page in order to use the security namespace:

<%@ taglib prefix="security"
  uri="http://www.springframework.org/security/tags" %>

The hasRole expression can now be used on the page, to show/hide HTML elements based on who is currently authenticated when the page is rendered:

<security:authorize access="hasRole('ROLE_USER')">
    This text is only visible to a user
    <br/>
</security:authorize>
<security:authorize access="hasRole('ROLE_ADMIN')">
    This text is only visible to an admin
    <br/>
</security:authorize>

3. Method Level Authorization Example – @PreAuthorize

Security Expressions can be used to secure business functionality at the method level as well, by using annotations.

The annotations @PreAuthorize and @PostAuthorize (as well as @PreFilter and @PostFilter) support Spring Expression Language (SpEL) and provide expression-based access control.

First, in order to use method level security, we need to enable this in the security configuration using @EnableGlobalMethodSecurity:

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

The equivalent XML configuration:

<global-method-security pre-post-annotations="enabled" />

Then, we can secure methods using the Spring @PreAuthorize annotation:

@Service
public class FooService {
    @PreAuthorize("hasRole('ROLE_ADMIN')")
    public List<Foo> findAll() { ... }
    ...
}

Now, only principals with ADMIN role will be able to call the findAll method successfully.

Note that the Pre and Post annotations are evaluated and enforced via proxies – in case CGLIB proxies are used, the class and the public methods must not be declared as final.

4. Programmatic Checking of the Role

A user authority can also be checked programmatically, in raw Java code, if the request object is available:

@RequestMapping
public void someControllerMethod(HttpServletRequest request) {
    request.isUserInRole("someAuthority");
}

And of course, without access to the request, the check can also be done manually by simply verifying if the currently authenticated user has that particular authority. The user can be obtained from the Spring Security context in a variety of ways.

5. Conclusion

This tutorial is a quick introduction to using Spring Security Expressions in general, and the hasRole expression in particular – as a quick introduction of how various parts of the application can be secured.

For the web authorization example, check out this Github simple tutorial. The method level security example is also on GitHub.

Leave a Reply

Your email address will not be published.