Search code examples
javaazurejspspring-security

request.isUserInRole for Azure-defined app roles


If I login through Azure 2-step authentication I can protect a Java/Spring method using an "Admin" role defined in the Azure Application configuration with:

@PreAuthorize("hasAuthority('APPROLE_Admin')")

If I use Spring Security and traditional Active Directory authentication and a group that maps to ROLE_Admin I can use the following to get a true/false to determine if the logged in user is in the role:

request.isUserInRole("ROLE_Admin")

But the same for Azure application roles always returns false, even when it should be true:

request.isUserInRole("APPROLE_Admin")

QUESTION:

Is there a way to call isUserInRole() for Azure application roles? Or perhaps an alternative approach that can be used in JSPs to determine if the logged in user is in a particular Azure application role?

REASON

I would like to use it in combination with JSP/JSTL to hide elements of the page that are only relevant if you are an Admin. This used to work great with traditional AD authentication but it is driving me insane now that I use Azure two-step authentication.


Solution

  • Spring diferentiates between roles and permissions by prefix, which is ROLE_ by default. Everything not starting with the prefix is not considered to be, well, a role. For that reason the isUserInRole method adds the prefix to its argument if it's not present there yet: SecurityContextHolderAwareRequestWrapper.java#L136. On the other hand, hasAuthority does not do it.

    Depending on your actual usecase, you have several options:

    1. Reconfiguring or removing the prefix used by Spring Security. See How do I remove the ROLE_ prefix from Spring Security with JavaConfig?
    2. Using hasAuthority instead of isUserInRole in your JSP:
    <sec:authorize access="hasAuthority('APPROLE_Admin')">
     ...
    </sec:authorize>
    
    1. Writing your own method to manually check authorities retrieved from SecurityContextHolder.getContext()