Spring boot 3 & Spring security 6 - Roles and Permissions Based Authorization Explained!

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
what's going on guys and welcome back to my channel in this video I will answer the question that you most of you has been asking which is how to implement roles and permission based authorization in Spring Security 6 and spring boot 3. so in this video I will guide you step by step how to implement this and how things really work and also you will have a deep understanding when to use what so because in Spring as you all know we can configure almost everything in different ways and in when we talk about authorizations and permission based and role-based authorization there are multiple ways how to configure that so I will guide you in this video step by step how to implement this and finally I will tell you which one to use and what are the use cases and the advantages of each configuration so if you're new to my channel just go ahead hit the Subscribe button and join me on YouTube also if you need to stay up to date and get my my latest news and the post that I'm posting almost every day I also want to invite you to follow me on social media on LinkedIn also my Instagram and I would be happy to see you part of our Facebook group and Discord server you will have all the links Down Below in the description of this video so with no further Ado let's get started first of all let me explain to you what are roles and permissions so in our application we have a user so we have the dedicated endpoints to register and to authenticate user so we have let's talk about registering a new user and a user we mentioned before that user has one role you can also change it and you can make the user or like give it many or multiple roles but let's focus on the existing first so we said that a user has a role and Rule is on the global application Level so we say user has a role a and then when we talk about resources or we want to go deeper in the details then we talk about permissions and permissions as you can see here in this example so we have a role a and it has many or multiple permissions and the permission is per resource so the permission which will be in this way so for example I have one rule a and then this role a is able to read from this specific resource right from another resource and so and so forth so here I just I need to highlight something don't stick to one resource so here we have this read permission and we can have this read permission multiple times depending on the resource so it hundred percent depends on the way you design your application and the way you want to limit or your way the way you want to control the permission and the access of your back end so here just to give you an overview or like a small example so a role a for example can access admin Administration resource or like the administration endpoint and he can read he can also access for example management resources and they can also perform a read request on there and the same for the right delete update and any other type of actions that you want so what we will be implementing first here we have already the role because when we create a user we assign a role to it now we need to create permissions or we need to Define permissions to our application now let's create some endpoints or some resources so here in this demo package where we have the demo controller right here so I'm just gonna copy this annotations I will create two controllers or two new resources so I'm gonna create a new Java class and they will call it admin controller and I will create another class I will call it management controller so this one it will have a rest controller so let me make it full screen so we have rest controller and we have request mapping and this one let me call it for example admin and then I will just I don't have a serviced so I don't need to uh to inject anything because I just want to demonstrate how permissions and roles works so here I will just create some some endpoints so I will have a get mapping and then public string get I will just call it like that to make it simple and I will simply return some some string so here let's say get admin controller for example or admin resource and I will duplicate this one to create others so here we have a post and this one it will be post mapping and I will just name this one post then I will have a put mapping the same here I will just name the method method put and here also put just to have the correct output when we try to invoke the different endpoints and finally I will add delete mapping and this one will be my delete operation so this is the first admin controller and then I want to create an a new controller which is for management for example for example in our application we will have a management role and admin role for example and we can also consider this demo controller is for user for example so I will just copy paste this admin controller and name it management and let me make it for the screen and this one I will make it management and then I will just replace this admin with management so I'm going to use a shortcut you can see it down here and I will call it management controller so now we have two controllers this one is should be accessible only by manager and admins and the admin controller is is going to be accessible only by the Admin itself so here management we will have management and admin or manager and the admin both of them they can access this endpoint and for the admin controller it will be only the admin who can access these resources or these endpoints so now let's move on since we spoke about roles so let's go to this role in um right here and I have user admin and I will just create a manager role so this is gonna be the new the new role I will assign to my different users and now we said that each role can have multiple permissions so in this case let's create first a new enum so a new class and then select inum and I will call it permissions or permission so in this permission in arm I will have set of permissions as we saw in the diagram in the beginning so this enum will hold the different permissions for the different resources so first of all let me create private final string permission so this is going to be the permission name and of course I will need the required RX Constructor because I don't need to I don't want to create my own the Constructor and here I will just add the getter now I'm gonna create for example I have admin read and then this admin read it will has or it will contain the permission to read a resource for an admin road so for example I can call it admin colon read or you can name it anything you want because this one it depends on you and the way you want to design this so then I will have also admin update so it's going to be admin called an update then I will have another one admin create for example and here it will be admin colon create so this one it would be for the post this one is for the boot mappings and this one is for the for the get and I will create admin delete so you as I mentioned before you can create as many permissions as you want so for example if you have for example a different read so on a different resource you can just name it read something on this resource so it's it really up to you how you want to design or how you want to create your permissions so this one it will be admin delete and I will just duplicate this one for the manager so I will add a colon here and I will just use the shortcuts and this one I will call it manager and then I will change this one to manager or management okay so we spoke about resources let's stick to that so the manager read has access or has the permission to read the resource called management all right so now we have the set of our permissions now let's go back and Link these permissions to the roles so here we said that we have a user admin and manager and now I will create and I will do the same thing as the permissions since the permission has a string which is the permission name and now the role has a set of permissions so I will create a private final set of type permission so permission just make sure that you import it from the correct place which is com.alible.security.user and I will call it permissions and why I'm using a set right here because I don't I don't want to have duplications on the permissions so for example if I have admin read or admin update two times it will accept only one so now I need of course the required RX Constructor here and then I will add the getter so I'm just I'm using lombok to avoid the boilerplate code and now we need to assign some roles so for example for the user let's say that the user has no permissions and to do that it will be collections dot empty set so we can use this one and then for the admin let me Define some permissions for the admin so the admin will have the following permissions for example so it will be set dot off and now I can Define that the different permissions for the admin so it will be admin read so now let me import this one static and I will click on add static import and then it will be the next one or the next permission admin update and then admin delete and of course admin create so now I have the set of the of permissions for the admin and as we mentioned before we want the admin to be able to read from the admin resource and also from the management resource so I will just rename this one to manage management or manager and again I need to import each of them so here whether you can call it manager or management because this is the permission for the manager to read and it will be again management read or you can just call it management so it's really up to you now I will just copy this one and assign these roles to the manager and they will just remove the admin because the manager as we mentioned the manager should be only able to read the management resource now after creating and assigning permissions to each of our roles you can also by the way create multiple roles and assign multiple permissions as you want so now after the permissions I will create a method I will call it public and this one should return a list of simple granted authorities so this object sample granted authorities is the one used by Spring and just I want to remind you from the previous video as we can see right here when we in the user object when we get authorities which is coming from the user details so this one we are returning a list of new simple granted authorities so spring understands this object so let's go back to our role right here and I will call it get user authorities for example or just get authorities let's call it authorities just to make it simple and now what I want to do is I want to do get permissions and then I will stream over the permissions and I will do a mapping I want to transform one permission or each permission to a new simple granted Authority all right and this simple granted Authority takes a string role or string Authority so in Spring roles and authorities are the same because spring will use this information to decide what who can access what and here it's gonna it's gonna be permission dot name and then of course collectors to list or to set so let's make it list and then I will assign this one to a variable and then we call it authorities equals this one and since we are using Java 17 already IntelliJ is proposing that we can transform or use to list directly now before or let's first return these authorities and before that what we need to do is to also assign the current role so for example when we when we get the admin.authorities we will return this one and also we need to return the role admin so finally I will do authorities dot add and then new simple granted Authority and then it will be this dot name because this dot name when we for example when we do roll dot get authorities this means that we are getting for example admin and then when we do this dot name it will be role so here we are missing something because when spring needs to work with authorities it has some prefix and it's always roll and restore something so when you need to work with roles make sure that you always think about this one whether you can remove it in the configuration or always think about role and then when we I will show you later on when we want to use these authorities and roles we don't need to specify this one so now after creating this method let's go to our user.java and here in this method get authorities and as I mentioned this method is already overridden and it comes from the user details so here instead of returning only the role we need to return the role dot get authorities and now spring will use the list of authorities of each user so now let's move to the configuration and then let's open the security config and I'm Gonna Make It full screen and in here we see that we have this configuration part for our security and we have here request matcher and now we are Auto authorizing everything or all the calls from this API V1 auth and anything now we need to secure the rest okay so here we have this one permit all and then let's first secure the management okay so here I will add a new request matcher and then for this request matcher I want any API slash V1 slash management slash anything star star means any any sub resource or sub endpoint of this management or of this URL and I want it to be accessible as we mentioned before by any user having the following roles so having the role admin and I can also import static admin from the from it's this one and then we need dot name and then so since it has any role so this any role it accepts already a list of string or an array of strings so here it will be also manager dot name so first I secured this endpoint to be only accessible by admin and manager now I can go a bit deeper and now I will start assigning permissions so here I will have again request matchers and now I want to secure them one by one so we said that for HTTP method dot get on the following endpoint so slash API slash management slash star star so I'm just gonna copy this one and this one should be accessible by people or users has any Authority now we are using authority to secure the different endpoints so let me import this one static and then for the authorities I want to have or I want to secure the get of the management endpoint to be only accessible by admin and management right okay so this one is going to be admin dot right sorry it should be read and then I can import it dot name and then it's also accessible by manager read dot name so here this endpoint is only accessible by people or users having the following Authority or permission which is admin read and manager read so I'm just gonna duplicate this one so the next one it will be post and then put and then delete for example so this is what we did and here for the post it should be admin right we call it admin create so let's use create and also this one should be manager create and then the next one for the put it should be admin update and also manager update so the next one or the final one it's admin delete and also management delete all right so now we secured this one so let me just separate them to be clear so here first just to remind you first we it we secured the management endpoint or like the whole management endpoint that should be only accessible by admin and manager and now I'm securing the different operations so the get it's only by admin and manager and post the same and so and so forth so I will just duplicate this one so here instead of management I will just rename it admin and then all I need to do is instead of has Authority I will make it sorry instead of has any Authority I will make it has Authority and I will remove the manager so this endpoint the admin endpoint the different um methods and resources are accessible only by admin also I will duplicate this one and here instead of management I will say admin and this one has role not any role but it should the user should have the admin role in order to access this endpoint all right so now we just secured the different endpoints and later on I will show you also how we can use or which annotations we can use in order to do exactly the same thing and after securing our different endpoints let's now insert some users so first of all I would I need to go to this authentication Service right here where we have the register method and we see here that we are automatically assigning a user role to any user that will be registered and I just want to make it dynamic in order to be able to create different roles so here I will go to this register request and after password I will create a private role role so here this means that now we will be able to create roles by dynamically but this one or like this field that I'm adding right here you need to think about the way you want to manage roles in your application and here I just added this rule just for the sake of this demo project so here instead of the role I will say request dot get row and now I have the rules that will be injected or assigned dynamically now let's go and insert some users so first let's go down to our Security application or the main class where we have the spring boot application so in this case I will add a new bin and it will be public command line Runner and with this command line Runner let's call it command line Runner I will be able to inject any bin of my application so I will inject a register service or I think we call it authentication Service yeah so let's call it service and then I will just need to return a Lambda and now in this case what I want to do I want at the application startup I want to insert some users so first I will create an admin equals registration request dot Builder and then build and this for registration request let's have a first name and I will say admin for example and then last name and I will also call it admin and then we will have an email so the email let's call it admin at mail.com and then finally we'll have well not finally but we will have a password let's call it password and finally we will have a role and now we can say admin okay so I also can import this one statically and then what I want to do is I want to print out the token that will be generated for this admin so here it will be just admin token and then it will be my service dot register and I have the admin and then get access token so here it will just print at the application startup it will print the at the token for the admin I will just duplicate this one two other times or like just let's say one time and here it will be manager so I will just rename this one and I will call it manager so here for the email I will call it manager and also for the role I will give it a manager role so now when I start my application I will have two users with two different roles and then I will show you how this is gonna be and how it will behave when we use the token for the admin or when we use the token for the manager so now let's start our application in debug mode and let's do a first test so here the application is starting and we see that we have an admin token and I just didn't rename that one so let me first do it and this one is manager token we can restart it later on and now I will use for example this admin token and I will go to postman and here I have already uh the call so it's it's going to be a post for example and for the admin endpoint here I will paste the token and click on send so we see that we hover for three which is not the expected behavior let's go back and check what happened so here first we see that we have an exception and this one it says that unsupported operation exception and here we have an abstract immutable collection and I think I know where this comes from is when we go to the role and here we just change this to list but let's use collect and then collectors to list and now uh okay so here I see another issue because here in when we use permission.name it will return the permission in this in this format so it will be manager underscore read which will not also be working so let me restart and show you what's gonna happen and here I will just open my application config and I will add a breakpoint to the user details service right here this method find by email and I will add breakpoint and here I want the breakpoint to be on the Lambda expression level let me make it full screen and now I will also reuse again the same token for the admin and I will send again the request so I will just replace the token hit send and now let me show you what we have right here so we have this call or we will be performing this call to the database let me evaluate this expression and by the way learning debugging is really important and really helps you to debug and check if you have any issues and I will create really soon a video for that and also if you are interested in learning how to debug on ntdj just drop a comment and I will create a video for that so now let's click on evaluate expression and here I will just do get and then get authorities or let's first start with the get here we see that this is the lazy load exception so we can just skip it for now and here we have this first name last name password and so on and so forth and now we can do get Authority and let's see the authority what's what is returning so it's returning manager delete manager update and so on so forth which is not the case so this is not what we want because as I mentioned before here we just made a small mistake so instead of name we need get permission so here if I continue and I go back to postman we see that we still have or we have this 200 okay but to make this really working fine instead of using name let's use get permission all right let's restart the application for a final time hopefully and I will use this admin token again and now I will try to access this admin endpoint so I will just remove this breakpoint and go back to postman so here we have a post admin controller if I try get the admin also is able to access that the get resource from the admin controller now let's let's try management and if I click on send we see that we have get manager or management controller now let's use the other token for the manager so from the console right here I will just copy the manager token and go back to postman and I will replace it so here we should get 200 okay when we try to access the management controller using a manager token but if I try to access the admin I should get a 403 so this is what we are getting so we have a 403 Forbidden because the manager is not able to access the admin endpoint or the admin resources so this is what we already defined in here so when I go back to the security configuration here we said that for the management has any Authority admin read write and so and so forth and then for the admin we stick only to one rule which is the admin role and only the authority that are that belong to the admin so admin read create update and delete so as as we saw right here when we try to access the admin endpoint using a manager token we get for three so if I try to go back to management and send again so here I get a 200 and also I get the response from my backend so now we saw how we can Implement authorizations and role based and permission based authorization in Spring boot let me show you how we can improve this or how we can use annotations to secure also the endpoint so follow me on that so now I will first comment this out and they can just go to code and then comment with line or with block comments so now I don't I no longer have the security or I'm no longer securing the different endpoints for the admin so now what I can do or what I need to do is to do the same thing or have the same behavior but I want to use annotations so I will open the admin controller and spring already offers us the same thing as we saw that we have or we can use the method has has Authority and has role which is this one I'm referring to this so here we have has Authority or has role we can also use them but with annotations so here for example for we said to replicate this one with annotations so we said that the admin controller should have or the user should have the role admin all right so now what I can do there is an annotation called pre-authorize and this pre-authorized it takes a string and the string is the method has role the same one that we used before and now in semicolon we need to provide the role that we want to use for this one so here it has role it should be admin so only admins they should be able to access this endpoint okay so now when it comes also because this pre-authorized annotation it goes on the method and the type level type means class and method is the method so we can use and use this annotation on the class level also on the method level so this one I will just paste it here and now instead of a role I will say has Authority and here it should be admin and then colon read so we need to use the name of the permission that we have so here we have the permission and now we need to use this one so it should be admin read admin update not this one okay so let's also continue this one or like Also let's do it here so now it's a post mapping so it's admin create and then it's admin update so be careful if you make a typo or a mistake while typing the permission name you will have issues accessing the endpoint so here it will be delete now there is one important information I need to share with you when you want to use this pre-authorized method you need absolutely to add an annotation you need to enable or to tell spring that you want to use this pre-authorized okay and now let's go back to our security configuration and on the class level I want to enable web or method security okay so if you are used or if you implemented this already in Spring to point something or like any version before the spring 3 the method used to used to be enabled enable global method security and as you can see this this annotation is deprecated and now it's we need to use a different one okay and here I just want to tell you the difference before we have uh within this annotation enable global method security we have a property right here called pre-post enabled so the pre-post enabled by default it's false and the pre-post enabled is or refers to this annotation okay so it's the pre-authorized so if you are working with a prayer version of of spring so any version before the spring 3 you need to use the enable global method security and don't forget here to say pre-authorize enabled to true because as I mentioned the default value of this pre-post enabled is false so think about making it true so let me remove this and now let me explain to you why we only need this enable method security because the pre-post enabled now is by default true so this is really important and if you are using as I mentioned a pre-version or like a version lower than spring 3 so think about enabling this pre-post enabled otherwise you don't need it all we need is just to have this enable method security all right so now let's restart our application and try to test again so I'm also running again the application in debug mode and I have the admin token and the manager token so I will just take the manager token and open my Postman so here we have management and I will just paste the new token I click on send so we still that we can always access the management controller so if I change it to admin and I try to access so we see always that we have 403 because the the manager should not be able to access the admin now let's try with the admin token so I will copy this again and then we go back to postman and I will paste the admin token and try to access it so we can see that with the admin token we are able to access any endpoint of the admin using this admin token now if I also try management and I click on send so we see also that we can access the delete operation from the management controller with the admin token all right now let me give you a small comparison or a smaller explanation when to use what like means I mean like when to use annotation based or when to use this kind of configuration both annotation based and configuration based role authorization methods in Spring Security have their own advantages and use cases so when deciding which method to use it depends on the requirement of your application and your preferred style of implementing security so let's first talk about the using The annotation or annotation based using The pre-authorized annotation you can also use other annotations to secure endpoint so let me give you some use cases or like when to use this this annotation or this way of securing your endpoints so when you want a fine-grained control over an individual method and their access also when you want to keep the authorization rules close to the code that affect and then when when the authorization rules may change dynamically as annotations can be easily updated without needed needing to configure or reconfigure the entire security setup so also the advantages of this annotation based is it provides a better readability and maintainability as authorization rules are placed directly on the method they protect also it allows the use of spring expression language or also AKA or as known as spel which is spring expression language for complex authorization rules finally it supports complex Access Control scenarios such as hierarchical roles and custom permission evaluators and now when we talk about configuration based authorizations using the request matchers so we use it when you want to centralize your security configuration in single place also when you have a clear and straightforward mapping between URLs and roles and also when you want to enforce Global secure security rules that apply to all endpoints in your application so for example if you want to secure all the get methods in your entire application it's really easier using the request matchers configuration and the advantages of this type of configuration it provides a clear overview of the entire security configuration so at a glance you can see the whole configuration of your application and the way you are securing endpoints also it allows for easy management of security rules as they are in one place and finally it offers a simple way to apply security rules to specific URL patterns so in summary the choice between annotation based and configuration based role-based authorization depends on really on your specific requirements and preferences so The annotation based authorization offers fine-grained control all and better readability while the configuration based authorization centralizes security rules and is easier to manage it's not uncommon to use a combination of both of them or applying Global rules through configuration and more specific rules through annotations so I hope now you know and you better understand the difference or like this small comparison between annotation based authorization or configuration based authorization and I hope you have a better clearance and a better understanding how to implement roles and permissions so that was it for this video I hope you really enjoyed and now you have a better understanding how to implement roles and permission based authorization in Spring boutiques and spring boot 3. also if you need anything or if you want to see new topics and new tutorials just go ahead comment down in this in this video and I will try to answer everyone and also I will try to create videos as you request also if you're new here and if this is the first time you see the alibu YouTube channel just don't forget to go and subscribe and also join me on social media it was really nice having you all today see you in next video
Info
Channel: Bouali Ali
Views: 9,675
Rating: undefined out of 5
Keywords: spring, jpa, data jpa, mapping, onetoone, one to one, spring data, many to one, manytoone, class, generatedvalue, persistence, repository, service, jparepository, jpa repository, uml, class diagram, design, software, engineer, software engineer, java, jakarta, javax, spring boot, springboot, security, spring security, aliboucoding, spring boot 3.0, spring boot 3, spring 3, jwt, filter, authentication, authorization, bearer, jjwt, oauth2, github, social connect, social login
Id: mq5oUXcAXL4
Channel Id: undefined
Length: 43min 13sec (2593 seconds)
Published: Mon May 01 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.