hasRole vs hasAuthority

The Prefix Rule

hasRole("ADMIN") checks for the authority ROLE_ADMIN. hasAuthority("ROLE_ADMIN") checks the exact same thing. hasAuthority never adds a prefix.

ExpressionLooks forMatches meera?
hasRole("ADMIN")ROLE_ADMINYes
hasAuthority("ROLE_ADMIN")ROLE_ADMINYes
hasAuthority("ADMIN")ADMINNo (classic bug)
hasRole("ROLE_ADMIN")errorSpring throws: role should not start with ROLE_
hasAnyRole("SELLER", "ADMIN")ROLE_SELLER or ROLE_ADMINYes
hasAuthority("order:refund")order:refundYes

See It in Plain Java

Example

This small program copies the logic Spring uses, so you can see why hasAuthority("ADMIN") fails:

import java.util.List;

public class Main {
    static boolean hasAuthority(List<String> granted, String authority) {
        return granted.contains(authority);
    }

    static boolean hasRole(List<String> granted, String role) {
        if (role.startsWith("ROLE_")) {
            throw new IllegalArgumentException("role should not start with 'ROLE_': " + role);
        }
        return hasAuthority(granted, "ROLE_" + role);
    }

    public static void main(String[] args) {
        List<String> meera = List.of("ROLE_ADMIN", "order:refund", "user:manage");
        List<String> asha = List.of("ROLE_CUSTOMER");

        System.out.println("meera hasRole(ADMIN)           = " + hasRole(meera, "ADMIN"));
        System.out.println("meera hasAuthority(ROLE_ADMIN) = " + hasAuthority(meera, "ROLE_ADMIN"));
        System.out.println("meera hasAuthority(ADMIN)      = " + hasAuthority(meera, "ADMIN"));
        System.out.println("meera hasAuthority(order:refund) = " + hasAuthority(meera, "order:refund"));
        System.out.println("asha  hasRole(ADMIN)           = " + hasRole(asha, "ADMIN"));
        try {
            hasRole(meera, "ROLE_ADMIN");
        } catch (IllegalArgumentException e) {
            System.out.println("Error: " + e.getMessage());
        }
    }
}

Output

meera hasRole(ADMIN)           = true
meera hasAuthority(ROLE_ADMIN) = true
meera hasAuthority(ADMIN)      = false
meera hasAuthority(order:refund) = true
asha  hasRole(ADMIN)           = false
Error: role should not start with 'ROLE_': ROLE_ADMIN

When to Use Which

  • Use roles for "who you are": customer, seller, admin. Few, stable, easy to read.
  • Use authorities for "what you may do": order:refund, report:export. Many, fine-grained, easy to give to one role without giving everything.
  • Many teams store permissions per role in the database and load both into the user's authorities at login.

Note: In OAuth2 resource servers (advanced level), scopes become authorities with the prefix SCOPE_, for example SCOPE_orders.read. You check them with hasAuthority("SCOPE_orders.read").