Java Spring Security Rules

Sample Project

Download this sample project configured with your Auth0 API Keys.

System Requirements
  • Java 7 or above
  • Maven 3.0.x or above
Show requirements

Rules are one of the cool features of Auth0. The reason is their flexibility, which gives you the ability to extend what Auth0 has to offer. They are just JavaScript functions which work like middlewares. To see a detailed description, please refer to the Rules documentation.

Create a Rule

To create a rule go to the Create Rule page. You can create it from scratch or use an existing template. These templates are written by Auth0 team to assist you complete common tasks.

Let's create a rule to implement some basic role-based authorization. If the user logs in using a @gmail.com or a @auth0.com email, the user will be assigned the ROLE_ADMIN role, otherwise the user will be assigned the ROLE_USER role. We will print some text on screen to see how this works.

The template you can use for this example is called Set roles to a user.

In our example we use this script:

function (user, context, callback) {
    user.app_metadata = user.app_metadata || {};
    var addRolesToUser = function(user, cb) {
        if (user.email.indexOf('@gmail.com') > -1) {
            cb(null, ['ROLE_ADMIN']);
        } else if (user.email.indexOf('@auth0.com') > -1) {
            cb(null, ['ROLE_ADMIN']);
        } else {
            cb(null, ['ROLE_USER']);
        }
    };

    addRolesToUser(user, function(err, roles) {
        if (err) {
            callback(err);
        } else {
            user.app_metadata.roles = roles;
            auth0.users.updateAppMetadata(user.user_id, user.app_metadata)
                .then(function(){
                callback(null, user, context);
                })
                .catch(function(err){
                    callback(err);
                });
        }
    });
}

Once you are done, save the rule.

NOTE: Keep in mind that this is just a starting template, you can edit it to meet your business needs.

Retrieve the Role

The web app will read this information from the UserProfile and apply the granted authorities when checking authorization access to secured endpoints configured with Role based permissions.

To do thi, edit the /src/main/java/com/auth0/example/AppConfig.java by replacing this:

.antMatchers("/portal/**").hasAuthority("ROLE_ADMIN")

with this:

.antMatchers("/portal/**").hasAnyAuthority("ROLE_USER", "ROLE_ADMIN")

Display Result

Let's display some info to see that our rule actually works.

Add the following code at the src/main/webapp/WEB-INF/jsp/home.jsp, inside your jumbotron div:

<p class="lead">
    <sec:authorize access="hasRole('ADMIN')">
        <label>This line is only visible if you have ROLE_ADMIN</label>
    </sec:authorize>
</p>
<p class="lead">
    <sec:authorize access="hasRole('USER')">
        <label>This line is only visible if you have ROLE_USER</label>
    </sec:authorize>
</p>

That's all the changes we need. Let's test this!

Test the Rule

Once you login, depending on the email you used, you should see one of the two texts we configured.

Role rule sample

Optional: Create a Demo Resource

In order to demonstrate the Role based authorization, let's create a resource which only an authenticated and authorized User with Admin rights can access.

NOTE: This is an optional step, used for demonstration purposes, you can skip it.

Create a new AdminService.java under /src/main/java/com/auth0/example. Paste the following code:

package com.auth0.example;

import com.auth0.spring.security.mvc.Auth0UserDetails;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

/**
 * Demonstration of method level Role based authorization
 * Only an authenticated and authorized User with Admin
 * rights can access this resource.
 *
 * Also demonstrates how to retrieve the UserDetails object
 * representing the Authentication's principal from within
 * a service
 *
 */

@Service
public class AdminService {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @PreAuthorize("hasAuthority('ROLE_ADMIN')")
    public boolean ensureAdmin() {
        final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        final Auth0UserDetails currentUser = (Auth0UserDetails) authentication.getPrincipal();
        logger.info("Current user accessed Admin secured resource: " + currentUser.getUsername());
        return true;
    }
}

Let's edit our HomeController.java to use this AdminService resource. We will autowire the AdminService resource, create a new adminChecks method and invoke it from the HomeController.

Paste the following code:

package com.auth0.example;

import com.auth0.Auth0User;
import com.auth0.SessionUtils;
import com.auth0.spring.security.mvc.Auth0JWTToken;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.servlet.http.HttpServletRequest;
import java.security.Principal;
import java.util.Map;

@Controller
public class HomeController {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private AdminService adminService;

    @RequestMapping(value="/portal/home", method = RequestMethod.GET)
    protected String home(final Map<String, Object> model, final HttpServletRequest req, final Principal principal) {
        logger.info("Home page");
        final String name = principal.getName();
        logger.info("Principal name: " + name);
        adminChecks((Auth0JWTToken) principal);
        final Auth0User user = SessionUtils.getAuth0User(req);
        model.put("user", user);
        return "home";
    }

    /**
     *  Simple illustration only
     */
    private void adminChecks(final Auth0JWTToken principal) {
        for(final GrantedAuthority grantedAuthority: principal.getAuthorities()) {
            final String authority = grantedAuthority.getAuthority();
            logger.info(authority);
            if (("ROLE_ADMIN".equals(authority))) {
                // just a simple callout to demonstrate role based authorization at service level
                // non-Admin user would be rejected trying to call this service
                adminService.ensureAdmin();
            }
        }
    }

}

Run the app and check that the logger displays the Current user accessed Admin secured resource message.

Use Auth0 for FREECreate free Account