The Master Class of "Learn Spring Security" is out:


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.

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, a URL pattern can be secured as follows:

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

Using Java configuration:

public class SecSecurityConfig extends WebSecurityConfigurerAdapter {
    protected void configure(HttpSecurity http) throws Exception {

Spring Security 4 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:


The latest version of the dependency can be checked here.

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

<%@ taglib prefix="security"
  uri="" %>

The hasRole expression can now be used in 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
<security:authorize access="hasRole('ROLE_ADMIN')">
    This text is only visible to an admin

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 older @Secured annotations did not allow expressions to be used. Starting with Spring Security 3, the more flexible annotations @PreAuthorize and @PostAuthorize (as well as @PreFilter and @PostFilter) are preferred, as they support Spring Expression Language (SpEL) and provide expression-based access control.

First, in order to use method level security, it needs to be enabled in the security configuration:

<global-method-security pre-post-annotations="enabled" />
For Java configuration, we need to annotate a @Configuration class with @EnableGlobalMethodSecurity:
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
Then, methods can be secured using the Spring @PreAuthorize annotation:
public class FooService {
    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:

public void someControllerMethod(HttpServletRequest request) {

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.

The Master Class "Learn Spring Security" is out:


  • Burak

    Is there any expression stating not hasRole in spring security ?

    • You can negate any expression using !: “!hasRole(‘ROLE_USER’)”.
      Hope that helps.

  • Florian

    First of all: Great Tutorial! Thanks!

    In the method “someControllerMethod”, the parameter is named request. In the body of the method it is called httpRequest.

    import javax.servlet.http.HttpServletRequest;

    public void someControllerMethod(HttpServletRequest request) {

  • Nice tutorial! I am trying to figure out how to define more than one role per access pattern. I have an application with lots of different MVC views and web flows, some of which need ROLE_ADMIN access, and others can also have ROLE_USER access, and others simply “isAuthenticated” access is enough. Some views (and web flows) are open to the public as well. Rather than have to go through and specify every single view as having access by ROLE_ADMIN, I would like to either just grant ROLE_ADMIN “/**” access, or if that isn’t possible, then is there a way to combine roles into the same access pattern?

    Something like the following maybe?


    • Sure – you can use ‘or’ as the logical operator to concatenate these 2 simple expressions.
      Also – check out the InternalSpelExpressionParser to see exactly how these will get parsed. Hope it helps. Cheers,

      • That’s awesome – thanks again!

        So after some more thought on this, I opted to simplify things a little by adding the following at the end of my security rules – since I want my ROLE_ADMIN to have full access to the application anyway:

        • That would do it as well. Another way may be to – if possible – separate the various areas by specific privileges and then have an admin that has these privileges. It only makes sense if your system is sufficiently complex and you need the flexibility, and from your previous message, yours may actually be sufficiently complex.

          • Dave McLure

            That’s a good point. In this case, I have a Roo-built scaffolding which I am looking to administer with the admin user. Unfortunately, my roo scaffolded CRUD directories, as well as my roo built webFlow directories are all placed at the root “WEB-INF/views” level by default, so it is a little messy to deal with when it comes to assigning security patterns. I suppose this is a downside to using roo, as opposed to building from scratch, where I might have opted to place my CRUD views into their own “WEB-INF/views/crud” subdirectory for easier security isolation pattern design.

          • I see – I personally don’t like Roo that much. However, if the base pattern has solved the problem, then that’s good. Cheers,

          • Dave McLure

            Roo is not perfect by any means, but as a person who has helped contribute to the effort a little, I feel I should defend it a little. I have found that Roo serves well to handle some of the more mundane aspects of creating, as well as maintaining a database schema to Java application CRUD layer, freeing up the developer to focus on coding and designing the application. I typically start with a database design tool, like Mysql Workbench, design my schema, then use Roo to reverse engineer it and build the basic application framework for getting started. I used to simply remove Roo at that point and go manual mode, but I have since learned that by keeping Roo in place it becomes super easy to refactor the database schema later and update the associated Java data structures as well. I do not like the default Roo “Active Record” persistence however, and always use the non-default jpa approach. This way I end up having much closer to the types of data layer as your application examples have – which are very well done by the way.

          • Hey Dave, thanks for taking the time to get into this. So – on Roo – it’s not that I don’t see the merit, it’s just a personal preference. In my experience, some of these tools are created and adopted with good intentions, but like code generation, ORMs (to some extent), GWT (Java compiled to Javascript) – they usually don’t pan out quite as you’d hope they would. If you really get what’s happening underneath – in the case of Roo – Spring – then they can definitely help. Even then – you have to consider the whole team – the fact that one person may get everything that Roo does may not mean that the whole team is as experienced. So – that’s why my personal bias is not towards it. Hope it makes sense. Cheers,

          • Dave McLure

            I think one unique Roo feature is the way it not only generates code, but with the help of AOP, it also help you refactor certain parts of it as well. I only wish that Roo initially generated code closer to yours, because if it did, then there would be a lot more successful Java programs running in the world. Roo is a living breathing project however, so I hope to see it evolve in a good direction. In the meantime, there are probably plenty of Roo Java coders out there who, like myself, could use a little help refactoring their Roo-generated code from (for example) default xml-based configurations into Annotation-based configurations.

          • Sounds good, and if it solves a problem – even better. As for evolving, I remember they announced that a company that had contributed a lot to Roo was taking lead on the project – so it’s probably in good hands. Cheers,

  • I’d also be curious to know how you are integrating external authentication schemes into your web apps – like this web site for example. I am assuming it is written in Java with Spring – correct? I’d be interested in what is involved in authenticating with Twitter, Facebook, Email, Disqus, etc. Are the tutorials on adequate to cover this, or did you run into any quirks? Also, what you have here seems to be more than simply an authentication scheme, as your framework seems to provide hooks into a variety of social sharing mechanisms. Please share (no pun intended).

  • yasser azizi

    I have a web application which has 2 actors:

    superAdmin & admin

    The superAdmin can determine all permissions of admin(eg: admin will use “add” methode and won’t use “delete”) So how can i do that?
    PS: I’m using Spring MVC + Spring security+hibernate+jsp

    • So – for your usecase, you don’t to do anything in particular with Spring Security. You will of course have to make the privileges dynamic if you want to change them in the application – so the UserDetailsService will have to be custom. It will grab the privileges/roles from the DB and fill them in on the principal. Then – it’s just a matter of having the operations that change these privileges only available to the super admin. Hope that helps. Cheers,

      • yasser azizi

        thinks! i’ll search for your ideas

  • indra sam

    is there any expression to user (ROLE_USER) ?, so every user is different to load query by userid ?

    • Hey Sam – not sure I follow – can you add a bit more detail to the question? Cheers,

  • Marcelo Salvador

    I am getting a null Principal on stateless calls. I need to set the principal to validate the role inside the principal against the hasRole check for every endpoint. Any thoughts will be greatly appreciated.

    • Hey Marcelo – that sounds like an interesting scenario but there’s really not enough info to be able to diagnose your problem. My suggestion is – post the full details on StackOverflow and reply here with the link (or shoot me an email) – and I’d be happy to take a look. Cheers,

  • Ciprian

    Hello Eugen,

    You stated that the intercept-url tag secures “a full page based on the URL”. Is it ok to secure an URL that does not redirect to a page but rather returns a JSON or xml as as Responsebody from an AJAX call, for example?


    • Hey Ciprian – the simple answer here is – yes it is. An URL is a generic concept so it doesn’t really matter (at this point) what type of data it’s returning. So yes, you can certainly secure URLs that are part of a REST API.