Learn Spring Security
Contents
Permission Based Authorization
We are yet to implement access restrictions to the below three APIs in order to meet the Security objectives defined in the first chapter.
API | Objective |
---|---|
Update Course | Instructor who created the course can only update it. |
Play Course | Instructor who created the course can only play it. Students who are enrolled on the course can only play it. |
View User Profile | Users can only view their profile. Any user can view an Instructor's profile. |
Downside of Role-based access control
We can apply role-based restrictions using hasRole() or hasAnyRole() on the above API urls. But role-based access control is abstract, coarse grained and less flexible. Any software requirement change in terms of API access control will require code change in the HttpSecurity configuration.
For example, if the Students can view the list of instructors in order to get the list of courses filtered by the selected instructor, we have to relax the access control to ListInstructors API for both Admin and Student users as below:
http
.csrf().disable()
.authorizeRequests(auth -> auth
.antMatchers(GET, PUBLIC_API_LIST).permitAll()
.antMatchers(API_LIST_STUDENTS).hasRole(ADMIN.name())
.antMatchers(API_LIST_INSTRUCTORS).hasAnyRole(ADMIN.name(), STUDENT.name())
.antMatchers(POST, API_CREATE_COURSES).hasRole(INSTRUCTOR.name())
.anyRequest().authenticated()
)
.httpBasic();
So we need a way to define and modify access control dynamically with out changing the code. We can do this by adding another logical layer using Permissions on top of Roles.
Permissions
Permission grants the ability to perform an action on a resource. By defining permissions for each action on each resource we can create fine grained access control. In technical terms we can define permissions for each API and then assign them to the appropriate Roles in the database. Similar to hasRole() Spring Security provides hasAuthority() method to restrict access to the API urls using these permissions.
So we will define each permission in the format ACTION_RESOURCENAME corresponding to each APIs. For example, PLAY_COURSE permission can be used to grant the ability to access PlayCourse API.
Key benefits of Permission-based access control
Securing each API by defining its own permission and then granting those permissions to the roles offer some of the key benefits listed below:
- No more code modification, as granting permissions to roles is database driven.
- Bird's eye view of who can do what in a single place i.e., database.
- Fine grained access control to each API (and other resources).
- Same permission-based access model can be used by both API as well as user interface, as every user action in the UI corresponds to an API execution in the application.
First let's apply the permission based access control for PlayCourse API. We will gradually build the concept in the next three chapters. And in the last chapter we will replace existing role-based access control using permissions.