Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between Role and GrantedAuthority in Spring Security

There are concepts and implementations in Spring Security, such as the GrantedAuthority interface to get an authority to authorize/control an access.

I would like that to permissible operations, such as createSubUsers, or deleteAccounts, which I would allow to an admin (with role ROLE_ADMIN).

I am getting confused as the tutorials/demos I see online. I try to connect what I read, but I think we treat the two interchangeably.

I see hasRole consuming a GrantedAuthority string? I most definitely am doing it wrong in understanding. What are these conceptually in Spring Security?

How do I store the role of a user, separate from the authorities for that role?

I'm also looking at the org.springframework.security.core.userdetails.UserDetails interface which is used in the authentication-provider referenced DAO, which consumes a User (note last GrantedAuthority):

public User(String username,              String password,              boolean enabled,              boolean accountNonExpired,             boolean credentialsNonExpired,              boolean accountNonLocked,              Collection<? extends GrantedAuthority> authorities) 

Or is there any other way to differentiate the other two? Or is it not supported and we have to make our own?

like image 558
Chinmay Avatar asked Oct 22 '13 18:10

Chinmay


People also ask

What is GrantedAuthority in Spring Security?

Interface GrantedAuthority Represents an authority granted to an Authentication object. A GrantedAuthority must either represent itself as a String or be specifically supported by an AccessDecisionManager .

What is difference between hasRole and hasAuthority?

The main difference is that roles have special semantics. Starting with Spring Security 4, the 'ROLE_' prefix is automatically added (if it's not already there) by any role related method. So hasAuthority('ROLE_ADMIN') is similar to hasRole('ADMIN') because the 'ROLE_' prefix gets added automatically.

What are roles in Spring Security?

The Role represents the high-level roles of the user in the system. Each role will have a set of low-level privileges. The Privilege represents a low-level, granular privilege/authority in the system.


1 Answers

Think of a GrantedAuthority as being a "permission" or a "right". Those "permissions" are (normally) expressed as strings (with the getAuthority() method). Those strings let you identify the permissions and let your voters decide if they grant access to something.

You can grant different GrantedAuthoritys (permissions) to users by putting them into the security context. You normally do that by implementing your own UserDetailsService that returns a UserDetails implementation that returns the needed GrantedAuthorities.

Roles (as they are used in many examples) are just "permissions" with a naming convention that says that a role is a GrantedAuthority that starts with the prefix ROLE_. There's nothing more. A role is just a GrantedAuthority - a "permission" - a "right". You see a lot of places in spring security where the role with its ROLE_ prefix is handled specially as e.g. in the RoleVoter, where the ROLE_ prefix is used as a default. This allows you to provide the role names withtout the ROLE_ prefix. Prior to Spring security 4, this special handling of "roles" has not been followed very consistently and authorities and roles were often treated the same (as you e.g. can see in the implementation of the hasAuthority() method in SecurityExpressionRoot - which simply calls hasRole()). With Spring Security 4, the treatment of roles is more consistent and code that deals with "roles" (like the RoleVoter, the hasRole expression etc.) always adds the ROLE_ prefix for you. So hasAuthority('ROLE_ADMIN') means the the same as hasRole('ADMIN') because the ROLE_ prefix gets added automatically. See the spring security 3 to 4 migration guide for futher information.

But still: a role is just an authority with a special ROLE_ prefix. So in Spring security 3 @PreAuthorize("hasRole('ROLE_XYZ')") is the same as @PreAuthorize("hasAuthority('ROLE_XYZ')") and in Spring security 4 @PreAuthorize("hasRole('XYZ')") is the same as @PreAuthorize("hasAuthority('ROLE_XYZ')").

Regarding your use case:

Users have roles and roles can perform certain operations.

You could end up in GrantedAuthorities for the roles a user belongs to and the operations a role can perform. The GrantedAuthorities for the roles have the prefix ROLE_ and the operations have the prefix OP_. An example for operation authorities could be OP_DELETE_ACCOUNT, OP_CREATE_USER, OP_RUN_BATCH_JOBetc. Roles can be ROLE_ADMIN, ROLE_USER, ROLE_OWNER etc.

You could end up having your entities implement GrantedAuthority like in this (pseudo-code) example:

@Entity class Role implements GrantedAuthority {     @Id     private String id;      @ManyToMany     private final List<Operation> allowedOperations = new ArrayList<>();      @Override     public String getAuthority() {         return id;     }      public Collection<GrantedAuthority> getAllowedOperations() {         return allowedOperations;     } }  @Entity class User {     @Id     private String id;      @ManyToMany     private final List<Role> roles = new ArrayList<>();      public Collection<Role> getRoles() {         return roles;     } }  @Entity class Operation implements GrantedAuthority {     @Id     private String id;      @Override     public String getAuthority() {         return id;     } } 

The ids of the roles and operations you create in your database would be the GrantedAuthority representation, e.g. ROLE_ADMIN, OP_DELETE_ACCOUNT etc. When a user is authenticated, make sure that all GrantedAuthorities of all its roles and the corresponding operations are returned from the UserDetails.getAuthorities() method.

Example: The admin role with id ROLE_ADMIN has the operations OP_DELETE_ACCOUNT, OP_READ_ACCOUNT, OP_RUN_BATCH_JOB assigned to it. The user role with id ROLE_USER has the operation OP_READ_ACCOUNT.

If an admin logs in the resulting security context will have the GrantedAuthorities: ROLE_ADMIN, OP_DELETE_ACCOUNT, OP_READ_ACCOUNT, OP_RUN_BATCH_JOB

If a user logs it, it will have: ROLE_USER, OP_READ_ACCOUNT

The UserDetailsService would take care to collect all roles and all operations of those roles and make them available by the method getAuthorities() in the returned UserDetails instance.

like image 127
James Avatar answered Oct 08 '22 09:10

James