{"id":1835,"date":"2026-05-22T14:37:02","date_gmt":"2026-05-22T12:37:02","guid":{"rendered":"https:\/\/kindsonthegenius.com\/blog\/?p=1835"},"modified":"2026-05-22T14:37:02","modified_gmt":"2026-05-22T12:37:02","slug":"inventoryms-springboot-roles-and-privileges-3-implementing-granted-authorities","status":"publish","type":"post","link":"https:\/\/kindsonthegenius.com\/blog\/inventoryms-springboot-roles-and-privileges-3-implementing-granted-authorities\/","title":{"rendered":"InventoryMS \u2013 SpringBoot Roles and Privileges 3 (Implementing Granted Authorities)"},"content":{"rendered":"<p>This is Part 3 of our implementation of SpringBoot roles and Privileges for our Inventory Management System (InventoryMS). In this part we would discuss and implement granted authorities in Spring Boot.<\/p>\n<p>Parts 1 and 2 can be gotten from the links:<\/p>\n<ul>\n<li><a href=\"https:\/\/www.kindsonthegenius.com\/inventoryms-implementing-springboot-roles-and-privileges-1\/\" target=\"_blank\" rel=\"noopener\">SpringBoot Roles and Privileges &#8211; Standard Roles\/Privileges in an Inventory Management System<\/a><\/li>\n<li><a href=\"https:\/\/www.kindsonthegenius.com\/inventoryms-springboot-roles-and-privileges-2-the-data-model-and-api\/\" target=\"_blank\" rel=\"noopener\">SpringBoot Roles and Privileges &#8211; The Data Model and API<\/a><\/li>\n<li><a href=\"https:\/\/www.kindsonthegenius.com\/inventoryms-springboot-roles-and-privileges-3-implementing-granted-authorities\/\" target=\"_blank\" rel=\"noopener\">SpringBoot Roles and Privileges &#8211; Access Restriction Using Granted Authorities<\/a><\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h4><strong>1. What are Granted Authorities?<\/strong><\/h4>\n<p>In Spring Security, we have the concept of Granted Authority. This represents a privilege or a permission granted to a user to perform a certain action.<\/p>\n<p><strong>What is difference between Role and Authority?<\/strong><\/p>\n<p>This two represent the same concept and are basically the same. The difference is how Spring Boot handle the prefixing. A role is expected to be prefixed with &#8220;ROLE_&#8221; but an authority is not.<\/p>\n<p>For example, the authority &#8220;ADMIN&#8221; is the same as the role &#8220;ROLE_ADMIN&#8221;.<\/p>\n<p><strong>hasRole() vs hasAuthority()<\/strong><\/p>\n<p>This is also the same in concept. When you use hasRole(&#8220;ADMIN&#8221;), Spring Boot would expect that your role is named &#8220;ROLE_ADMIN&#8221;. However, if you use hasAuthority(&#8220;ADMIN&#8221;), Spring Boot would check if you have to role &#8220;ADMIN&#8221;<\/p>\n<p>In our InventoryMS project, we would be using hasAuthority().<\/p>\n<p>&nbsp;<\/p>\n<h4><strong>2. Design the REST API Endpoint Pattern<\/strong><\/h4>\n<p>To be able to achieve and efficient way to protect your API, you will have to design the routing pattern. What does this mean? It means you need some hierarchy for the API route. For example:<\/p>\n<ul>\n<li><strong>top level:<\/strong> version number would (\/v1)<\/li>\n<li><strong>next level<\/strong>: modules for example, \/orders, \/products and \/suppliers<\/li>\n<li>from here you can have methods GET, POST, PUT and DELETE<\/li>\n<\/ul>\n<p>With this we would be able provide authorization at a granular level<\/p>\n<p>&nbsp;<\/p>\n<h4><strong>3. Retrieving the User&#8217;s GrantedAuthorities<\/strong><\/h4>\n<p>To be able to protect our REST API based on user roles, we would have to do the following:<\/p>\n<p><strong>return the users authorities (privileges) from UserPrincipal<\/strong><\/p>\n<p>Here, we would need to update the getAuthorities method of the UserPrincipal class so that it returns a lit of SimpleGrantedAuthorities.<\/p>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #555555; font-weight: bold;\">@Override<\/span>\r\n<span style=\"color: #008800; font-weight: bold;\">public<\/span> Collection<span style=\"color: #333333;\">&lt;?<\/span> <span style=\"color: #008800; font-weight: bold;\">extends<\/span> GrantedAuthority<span style=\"color: #333333;\">&gt;<\/span> getAuthorities<span style=\"color: #333333;\">()<\/span> <span style=\"color: #333333;\">{<\/span>\r\n    <span style=\"color: #008800; font-weight: bold;\">return<\/span> userPrivilegeAssignmentService<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">getUserPrivileges<\/span><span style=\"color: #333333;\">(<\/span>user<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">getId<\/span><span style=\"color: #333333;\">())<\/span>\r\n            <span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">stream<\/span><span style=\"color: #333333;\">()<\/span>\r\n            <span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">map<\/span><span style=\"color: #333333;\">(<\/span>privilege <span style=\"color: #333333;\">-&gt;<\/span> <span style=\"color: #008800; font-weight: bold;\">new<\/span> SimpleGrantedAuthority<span style=\"color: #333333;\">(<\/span>privilege<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">getDescription<\/span><span style=\"color: #333333;\">()))<\/span> <span style=\"color: #888888;\">\/\/ Use SimpleGrantedAuthority<\/span>\r\n            <span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">collect<\/span><span style=\"color: #333333;\">(<\/span>Collectors<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">toList<\/span><span style=\"color: #333333;\">());<\/span>\r\n<span style=\"color: #333333;\">}<\/span>\r\n<\/pre>\n<p>&nbsp;<\/p>\n<h4><strong>4. Configure Authorization Rules<\/strong><\/h4>\n<p>At this point we would have to configure the permission on the routes. So we would have to check if the user has the required authority before the request is permitted.<\/p>\n<p>The following changes would need to be made:<\/p>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #333333;\">...<\/span>\r\n<span style=\"color: #333333;\">...<\/span>\r\n<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">authorizeHttpRequests<\/span><span style=\"color: #333333;\">(<\/span>auth <span style=\"color: #333333;\">-&gt;<\/span> auth\r\n                <span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">requestMatchers<\/span><span style=\"color: #333333;\">(<\/span><span style=\"background-color: #fff0f0;\">\"\/register\"<\/span><span style=\"color: #333333;\">).<\/span><span style=\"color: #0000cc;\">permitAll<\/span><span style=\"color: #333333;\">()<\/span>\r\n                <span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">requestMatchers<\/span><span style=\"color: #333333;\">(<\/span><span style=\"background-color: #fff0f0;\">\"\/login\"<\/span><span style=\"color: #333333;\">).<\/span><span style=\"color: #0000cc;\">permitAll<\/span><span style=\"color: #333333;\">()<\/span>\r\n                \r\n                <span style=\"color: #888888;\">\/\/Configuration for the product module<\/span>\r\n                <span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">requestMatchers<\/span><span style=\"color: #333333;\">(<\/span>HttpMethod<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">GET<\/span><span style=\"color: #333333;\">,<\/span> <span style=\"background-color: #fff0f0;\">\"\/api\/v1\/products\"<\/span><span style=\"color: #333333;\">).<\/span><span style=\"color: #0000cc;\">hasAuthority<\/span><span style=\"color: #333333;\">(<\/span><span style=\"background-color: #fff0f0;\">\"VIEW_PRODUCT\"<\/span><span style=\"color: #333333;\">)<\/span>\r\n                <span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">requestMatchers<\/span><span style=\"color: #333333;\">(<\/span>HttpMethod<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">POST<\/span><span style=\"color: #333333;\">,<\/span> <span style=\"background-color: #fff0f0;\">\"\/api\/v1\/products\"<\/span><span style=\"color: #333333;\">).<\/span><span style=\"color: #0000cc;\">hasAuthority<\/span><span style=\"color: #333333;\">(<\/span><span style=\"background-color: #fff0f0;\">\"CREATE_PRODUCT\"<\/span><span style=\"color: #333333;\">)<\/span>\r\n                <span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">requestMatchers<\/span><span style=\"color: #333333;\">(<\/span>HttpMethod<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">DELETE<\/span><span style=\"color: #333333;\">,<\/span> <span style=\"background-color: #fff0f0;\">\"api\/vi\/product\"<\/span><span style=\"color: #333333;\">).<\/span><span style=\"color: #0000cc;\">hasAuthority<\/span><span style=\"color: #333333;\">(<\/span><span style=\"background-color: #fff0f0;\">\"DELETE_PRODUCT\"<\/span><span style=\"color: #333333;\">)<\/span>\r\n                \r\n                <span style=\"color: #888888;\">\/\/Configuration for the order module<\/span>\r\n                <span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">requestMatchers<\/span><span style=\"color: #333333;\">(<\/span>HttpMethod<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">GET<\/span><span style=\"color: #333333;\">,<\/span> <span style=\"background-color: #fff0f0;\">\"\/api\/v1\/products\"<\/span><span style=\"color: #333333;\">).<\/span><span style=\"color: #0000cc;\">hasAuthority<\/span><span style=\"color: #333333;\">(<\/span><span style=\"background-color: #fff0f0;\">\"VIEW_PRODUCT\"<\/span><span style=\"color: #333333;\">)<\/span>\r\n                <span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">requestMatchers<\/span><span style=\"color: #333333;\">(<\/span>HttpMethod<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">POST<\/span><span style=\"color: #333333;\">,<\/span> <span style=\"background-color: #fff0f0;\">\"\/api\/v1\/products\"<\/span><span style=\"color: #333333;\">).<\/span><span style=\"color: #0000cc;\">hasAuthority<\/span><span style=\"color: #333333;\">(<\/span><span style=\"background-color: #fff0f0;\">\"CREATE_PRODUCT\"<\/span><span style=\"color: #333333;\">)<\/span>                                \r\n                <span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">anyRequest<\/span><span style=\"color: #333333;\">().<\/span><span style=\"color: #0000cc;\">authenticated<\/span><span style=\"color: #333333;\">()<\/span>\r\n        <span style=\"color: #333333;\">)<\/span>\r\n<span style=\"color: #333333;\">...<\/span>\r\n<span style=\"color: #333333;\">...<\/span>\r\n<\/pre>\n<p>Then we would have to repeat this for all other roles we identified.<\/p>\n<p>You could also create an enum type to hold these roles instead of using just strings. But I see no added benefits for taking this extra step.<\/p>\n<p>Note that in our application, we use Roles only as grouping for privileges.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This is Part 3 of our implementation of SpringBoot roles and Privileges for our Inventory Management System (InventoryMS). In this part we would discuss and &hellip; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_mi_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0},"categories":[414],"tags":[],"_links":{"self":[{"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/posts\/1835"}],"collection":[{"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/comments?post=1835"}],"version-history":[{"count":1,"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/posts\/1835\/revisions"}],"predecessor-version":[{"id":1836,"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/posts\/1835\/revisions\/1836"}],"wp:attachment":[{"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/media?parent=1835"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/categories?post=1835"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/tags?post=1835"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}