Using static variables in Spring annotations

Try the following which uses Spring Expression Language to evaluate the type:

@PreAuthorize("hasRole(T(fully.qualified.OtherClass).ROLE)");

Be sure to specify the fully qualified class name.

Documentation


Try something like this:

@PreAuthorize("hasRole(T(com.company.enumpackage.OtherClass).ROLE.name())");

If your OtherClass enum is declared as public static, then you need to use $ sign:

@PreAuthorize("hasRole(T(com.company.ParentTopLevelClass$OtherClass).ROLE.name())");

name() to prevent futer problems if toString() will be overriden later


To make it possible to write expressions without package names:

<sec:global-method-security>
    <sec:expression-handler ref="methodSecurityExpressionHandler"/>
</sec:global-method-security>

<bean id="methodSecurityExpressionHandler" class="my.example.DefaultMethodSecurityExpressionHandler"/>

Then extend the DefaultMethodSecurityExpressionHandler:

public class DefaultMethodSecurityExpressionHandler extends org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler {

    @Override
    public StandardEvaluationContext createEvaluationContextInternal(final Authentication auth, final MethodInvocation mi) {
        StandardEvaluationContext standardEvaluationContext = super.createEvaluationContextInternal(auth, mi);
        ((StandardTypeLocator) standardEvaluationContext.getTypeLocator()).registerImport("my.example");
        return standardEvaluationContext;
    }
}

Now create my.example.Roles.java :

public class Roles {

    public static final String ROLE_UNAUTHENTICATED = "ROLE_UNAUTHENTICATED";

    public static final String ROLE_AUTHENTICATED = "ROLE_AUTHENTICATED";
}

And refer to it without package name in annotations:

@PreAuthorize("hasRole(T(Roles).ROLE_AUTHENTICATED)")

instead of:

@PreAuthorize("hasRole(T(my.example.Roles).ROLE_AUTHENTICATED)")

Makes it more readable imho. Also roles are now typed. Write:

@PreAuthorize("hasRole(T(Roles).ROLE_AUTHENTICATEDDDD)")

and you will get startup errors that wouldn't have been there if you wrote:

    @PreAuthorize("hasRole('ROLE_AUTHENTICATEDDDD')")

You can also create a bean container with roles, like:

@Component("R")
public final class RoleContainer {
  public static final String ROLE_A = "ROLE_A";
}

then on controller you can use:

@PreAuthorize("hasRole(@R.ROLE_A)")