Spring Boot 3.0 + Spring Security 6 | JWT Authentication & Authorization

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
welcome to cracket in this video we are going to discuss everything about implementing Spring Security in our application using JWT by the end of this crash course you will have a solid understanding of how we can Implement Spring Security and how we can use JWT token in our Spring Security for authentication and authorization so without further delay let's dive into the world of Spring Security and we have created this video as per our subscribers interest so I request you all to let us know in the comment section if you want to discuss any specific topic or if you want to discuss any crash course we are we are happy to do that please just let us know in the comment section and if you like the content please like share comment and subscribe the video what code are we going to write in this video so in this video we'll be H we are going to write a service and that service will be a cracket service and that in that service will create multiple APA end points so and those endpoints will use JWT token for its authentication and authorization so that is what we are going to do so if you see here we are going to create two endpoints slash register and slash authenticate and those will be unsecured endpoints or endpoints with no security or no JWT token it is because let's assume this is the first time you're going to log into an application and let's say that application has a cracket application so you need to register yourself to that application by that time you are a new user and you need to provide all your all your information to register yourself as the user so in the slash register endpoint you will provide all your details like first name last name phone number and you will register yourself to this cracket application so registration is the first process and hence this is in unsecured endpoint because you are new to the user you you won't be having anything related to this application next is authenticate so you are successfully registered then uh if you let's assume you you you think of Google so to log to the Google you need to provide your username and password so that is this authenticate so you will provide your username and password and you prove that you are already a user of this cracket application and the credentials that you have passed is valid then you will be authenticated to that end point and you will get a JWT token in return so you will use that jwd token to access other end points so that is why this authenticate is also a unsecured endpoint so you have two endpoints those are unsecured one is to register yourself as a user and the second one is to authenticate yourself as a user and in turn you will get a jwd token to access the other endpoints and also in this cracket application we have two roles one is admin role and the other one is member role so we are going to write two endpoints admin read and admin write and those two endpoints will be accessed one by those users who are registered as admin and we are going to expose two other end points which are nothing but the member read and member right and those two endpoints will be accessed only by those who are registered as member so if suppose my role is member can I access the admin and points like slash admin read no that is not possible so we are going to write role based implementation also in our code using the JWT token so because it is because in our JWT token we will Define what roles the user has so if like if the if you remember this/ authenticate endpoint will return me a JWT token and that JWT token will have all the information about the user so that JWT token will have information about whether the user is a admin or a member if he is a member he'll be he'll be allowed to access only the member read and member right end points and if he is an admin he'll be having access to access a admin read and admin write end points so with this we are clear we are going to write six end points two and secured and four are secured and in those we are going to implement role based authorization as well so we are also going to implement role based authorization based on the authorities if suppose my authority is admin colon read I will be able to access only the admin slre endpoint and not the right endpoints if suppose my authority is admin colon right I will be able to allow to access uh only the admin WR end points and not the admin read end points similarly for the member roles if I have member read Authority then I will be able to access member read endpoints and if I have member right Authority then I will be able to access member right end points so we are going to add authorities as well which means adding method level Securities as well so if we have just role implementation that will be the class level security and if we have authorities added then it will be method level security so we are going to uh Implement everything unsecured endpoints secured endpoints with just the roles secured endpoints with roles and authorities so write code for the JWT authentication it is always good to understand the Spring Security architecture we already covered a video in our YouTube channel for the Spring Security architecture I request you all to go through that video I'll provide the link here and in the description so if suppose uh anyways I'm going to give like give a gist of what how Spring Security architecture works but I have explained in detail in that video that will be really really helpful for this video so I request you all to go through that video so when the request comes to the uh Spring Security architecture what will will happen when request comes it will first go go to the Spring Security filters there will be multiple filters in the spring security so it will go through the all the filters that is available so one of those filters may be JWT authentication filter yes we are going to write JWT authentication filter in our code since we are implementing uh JWT in as a part of this tutorial so we are going to write this JWT authentication filter so our request will go through multiple filters and in that one of those filters will be JWT authentication filter so this JWT authentication filter that we write in our code is going to return a authentication object to the authentication manager so what will the Spring Security filter do the Spring Security filters will hand over the request to the authentication manager but it will hand over the request as an authentication object authentication is object is nothing but the username and password but the spring security object needs that username and password in the form of the authentication object so this Spring Security filter or the JWT authentification filter that we are going to write is going to return the authentication object to the authentication manager so what will this authentication manager do the authentication manager that we are going to use is the provider manager I'll show you when I write the code so this authentication manager will hand over the request to the authentication provider so the actual logic of authentication will be will be here in this authentication provider since in our demo we are going to fetch the user details from the database we are going to use Dao authentication provider as a uh like it is same like filters we can have multiple Dao multiple authentication providers in our application so even if one authentication provider fails for the authentication it will go check for all the available authentication provider and then only it will hand over the request to the authentication manager so one more thing we need to understand is that this authentication providers uses the user details service and the passcode encoder of the Spring Security architecture so in our example we will create this Bean user details service Bean as well it is because we are using the email ID as the uh username so we need to override that uh specific part of the spring Securities architecture so we will overwrite this user details service being in our application also we are going to use bcrypt encoder in our application for the encoding the password so this part this Bean also we will create so uh if you uh if you if you go through that video it will be really helpful the Spring Security architecture video so we will use uh we will override this user detailed service Bean we will overwrite this uh password encoder bean and we will create we will hand over the uh response to the Authentication manager so the actual authentication logic will happen here in the authentication provider using the US user details service and the password encoder then it will hand over the response to the authentication manager and this authentication manager in turn hands over the request to the sorry response to the Spring Security filters now the Spring Security filter before sending the response to the client it will store its uh security context which is nothing but the response from the authentication provider it will store that information in this security context so we will do this step as well why because we need to know who's the principle what are his authorities what is his credential so we need to know all the information we will do this step as well in our code we will store those information in our security context and then we will send the response to the user that response is like going to the controller and do whatever they want it is not like sending the response to the client it will forward the request to the controller so before the request reaching the controller it has to go through all these steps and we will override all these things in our code so it before we start writing the code let's try to understand what are we going to write in our code so this is purely on the implementation uh flow that we are going to do so if suppose a request comes my client is Postman so if I hit the any end point from the postman what will happen in my application I I'll check whether that is a wh listed URL or not so what is a whit listed URL Whit listed URL is nothing but the unsecured end points so if that is a white listed URL the flow will directly go to the controller and the controller in turn will respond back to the client with an appropriate response that may be a success response or bad request or that may be anything but the request flow will be like very simple it will check whether it's a wh listed URL if it's a wh listed URL it's it will directly route the request to the controller and from the controller the it the controller will return the response so this is the flow if suppose it is not a whitelisted URL meaning it is a secured endpoint then what will happen as I told earlier in the spring architecture it will go to the Spring Security filter chain so in likewise in the filter chain we are creating one filter and that is nothing but the JWT o filter so as a part of the flow code flow we will implement we will write this JWT or filter and in that JWT or filter we will verify whether the user is present in the database or not if the user is not present in the database immediately we will throw an exception to the client saying that the the user that have sent is not present in my database as user not exist exception if suppose the user is present I'll check whether the user has entered a proper credentials so meaning the username and the password is correct for that user or not I'll verify that how will I verify that I have I we are going to write a service called as the user Detail Service as I told earlier in the Spring Security architecture I have shown you one user details service and the password encoder if you remember with the help of that user details service I will validate whether my user is valid or not so I have a DB that is why I told uh when I was explaining the Spring Security that we will be using da authentication provider we are going to use a database so from the database I'll check whether the credentials are valid or not if the credentials is not valid invalid then I will throw a exception saying that your credentials are not valid please uh send me a proper credential information so if suppose the user is valid then what will I do I need to check whether the request that I have received I will uh I will extract my request and in the header I'll check whether the JWT token is present in the authorization header or not if the JWT token is not present again I'll send them uh send my request back to the clients saying that JWT token is mandatory for your request please send the request along with the JWT information because we are performing the authorization using the jwd token so please send jwd token as a part of the header in your request I'll send that exception back to the client if suppose the jwd token is present then we need to valid Val the JWT token so how will we validate the JWT token we will validate whether the signature is matching with the token or not whether the user is valid whether the sender is legitimate whether the jwd token is not expired whether the jwd token is uh yeah we will check all these information we we will uh verify few of the informations as well I'll explain you when we were writing the code so we will check all these information and if suppose the jwd token is invalid uh let's assume that the jwd token is expired then what will we do immediately we will send the response back to the client saying that your JWT token is invalid please send me a valid JWT token if suppose the JWT token is valid then what will I do I will perform my my I I've done everything I've done all my validations I have verified the user I I have verified the jwd token then now I will my response ready that is that needs to be sent to the controller but before sending to the controller I have to save the user information meaning the principal the authorities and few other information to my context holder security context holder so I will save that information to my security context holder and then I'll forward my request to the controller and the controller in turn will provide an appropriate response to the client so in the secured API endpoints we have like many steps in which we will check whether the wh listed URL or not and we will check whether user exists whether jwd token exists whether the jwd token is valid if all perfect then we will save the user information to the security context holder the user information like principal then we will forward the request to the controller so we are going to write code for everything and we in this everything is included JWT authentication and authorization so we are going to write code for it since we are going to write the code for JWT demo from the scratch or since it is a crash course for the Spring Security J WT I'm I'm I'm creating the project so I'm creating the project using the spring initializer if you see here this is the URL and you can see that I'm selected the languages Java and I'm going to use Maven as my dependency and I have selected the latest stable version which is 3.2.3 and I have given the group name as cracket and the artifact name as Spring Security JWT and I have provided the description which is nothing but demo project for Spring Security JWT demo and I have chosen the packaging as jar and the Java version as 17 also if you see here I have added five dependencies one is spring web since we are going to expose our apis we need to use spring web dependency and to avoid the boilerplate code I have added this lombo dependency I'm going to use postgress database in my application so I have added postgress SQL server and since we are uh using the Java persistence APA which is nothing but jpa I'm using spring data jpa to avoid the boiler plate code and to ease my query writing and we are using Spring Security yes for implementing JWT we need to add the Spring Security dependency as well so let me generate the project and I'll open it in intell we are going to use postgis database in this demo that's why make sure you have postgis running in your machine if you're using some other database make sure that database is running in your local since I'm using postgress I'm making sure sure that postgress is running in my machine and you can see that postgress is running in the port 5432 also I have created a database named Spring Security to use for this demo so I don't have any tables in it I am a to create the schemas and table for now I'm just showing you that my postgress is running in Port 5432 and I'm going to use this Spring Security database for my demo I have opened the application in intellig I just made on change previously it was application do properties I have changed it to application. yaml file and I have added the data source configurations here so if you remember we are using postgress yes that is why I have provided jdbc colon postgress SQL and my postgress is running in the port 5432 and that's why I have provided Local Host colon 5432 and the database that I'm going to use is Spring Security as I just showed so this is my data source URL username and password I will populate it after the video and uh while while executing the program and for the data driver class name I have provided or postgress SQL driver so we have done with the database configurations I have added jpa configurations as well I have create created this as create drop because I'm going to use this table only for the demo purposes so while the application start up it will create the tables and if I exit the application will drop the tables so I'm just creating this for this demo and that's why provided as create drop and I I want to see the SQL queries and that's why I have given the show SQL as true and I want to format the SQL queries and that is the reason I have given format SQL to true and the database as I told earlier we are using postgress SQL and the for the database platform we need to for the dialect actually we need to provide the postgress SQL dialect so all these configurations will change accordingly if you you are using different database you need to provide those database configurations here since I am using postgress I have provided all the postgress configurations here so if we start the application you can see that the application has been started and you can see one one thing here which is nothing but using generated security password and we got a password so I'll explain it what it is uh like in few seconds but for now I wanted to show you that I have added this database configurations here so our data source configurations are well and good and we can see see that our application is started and it is started in the port 8080 so I'll do one thing I'll open this uh 8080 in the Chrome and I'll show you something so i' I'm I'm going to Chrome and if you see if I give Local Host 8080 automatically slash login is appended and a new UI got generated so do you know how this is generated did we write any code for it no we didn't write any code it is just because of the Spring Security dependency we have added added so I want to show you that dependency as I told earlier in the demo just a minute yeah this is our pom.xml and if you see this here in the p. XML we have this dependency spring boot stter dependency this spring boot stter dependency is like a magic just if you add this dependency in your code you will be able to see this password will get generated which is the default password for your uh application or which is the generated password for your application and when you need to log to that application the what you need to do you need to provide this password here and the username default is the user let's try with user and the generated password the password we need to take it from here so I'm taking the password from from here and I'll go to this chrome I'll provide the password here and if I sign in you can see that I didn't I didn't write any a API that is why it is going to that white label error P if I have some a API and if I provide a valid API URL here it will populate the data so what we need to uh we need to understand here is that this Spring Security dependency is like a magic wherein if we just add this dependency we will be able to see a login screen wherein we need to provide the username and password so by just adding this dependency my entire application has become secured without the username and password I won't be able to log to my application I won't be able to see any apis that has been present in my application my application has become secured that is why we need uh Spring Security and uh with spring boot it's like very easy no nothing no code you need to write everything will come from this dependency that is why we have to use spring boot it's a powerful framework wherein it provides most of the features to us and if we just focus on our business functionalities that's that's enough there's no need for us to put effort to write the coding for the security so anyways if we just add this dependency we will be able to write the we will be able to secure our application also this is a default generated password if you want to change your password yes we can do that I'll show that in in this demo itself how we can change the password and all also the default username is user so so if you want to log to that application you need to provide the valid username and password and then only you will be able to log to that application and that application is sorry yeah I have logged in it by default it will go to slash login page and we need to provide the username and password since I have provided already the username and password I'm uh this is navigating me to this error page it is because I didn't configured any AP and and there's nothing in it that's why it's going to this error page so even to show this error page I have provided the username and password my application is secured using the spring API just with that dependency that is its magic so when we start our application we we provided our credentials if you remember we have provided the username and the password so from where that user came from so if we if we Deep dive into the spring security code we we have some class called as users so I'll search that class so I'll just give user I'll go to the classes and I'll go search for it so if you see here we have a class called user and that is implementation from the Sprint security so that user has lots of things which is nothing but username password authorities authorities is nothing nothing but the roles that we Define for a specific user is this users account non-expired is this users users account nonlocked is users credentials non-expired is this user is enabled or not so we have lots of properties that is defined for this user so when we when uh we just provided our username there that user will get internally mapped to the spring Securities user object if we didn't write any implementation for user in our code previous uh like we as we just seen in the demo we didn't write any implementation where will that user go that user will come here to this user and if you see here this user is implementing user details and this user details is having all the gets like username password as non account expired and like this so so we we have this user class which is implementing this user details so we can reuse this user object in our class or what we can do is we can write our own code so why am I talking about this user so if we are use going to use JWT token in my Spring Security that JWT token should should do authentication and authorization so for if authentication and authorization is involved in my application then I need to know I need to have a user for that so that user is nothing but the user in the Spring Security which provides which is which is provided by the Spring Security or if we want to have more control over the user class we can create that user class so in our demo we are going to create a user class and we are going to implement this user detail else so why are we implementing it because this is tested by the spring framework and it will have it has many features so I want to I want to implement this user details I want to implement all the I want to use all the features that Spring Security provides but I want to have the control but if I use this user Spring Security has the control if I want to add one more field I won't be able to add so what I'm going to do is I'm going to create a class user which is going to implement this user details so for now what are we going to do we are going to write code everything like write all the code related to this user object so what are we going to do we are going to for if suppose we are going to create an user and to create that user we need to create a table for this user and we are going to create write a repository for this user we are going to write this user class as well that's what we are going to do let's start writing the code for that that we have created that we discussed that we are going to create since we need to have control of this user class uh we are returning this class and that is implementing user details as as I told earlier this user details if you see this is from the Spring Security Co framework so we are going to use this user details only so I have implemented this user details in for the class user and you can see that this is an entity and the table name is underscore user the reason why I'm using underscore user is in postgis uh database only this user is not allowed so I have given it as underscore users if you're using some other DB and that DB is allowing you to create a table name with User it's well and good you can create uh table with just the user for if you're using postgis you need to use underscore user so for the table name I have provided underscore user and I have annotated with at entity yes this is my entity class and that's the reason I have provided with at entity I have provided the table name and these are the long Bo annotations that I have added at data for the Setters and gets and at Builder annotation for the Builder design pattern and at and at allog Constructor for the constructors for my Constructor so this is the class that have I have created and I have provided the first name of the user last name of the user email and the password so in the previous user class that I show we have the uh we have the username so for the username I want to provide the email ID that is why I have cre created uh Ive created the field name as email ID so you can see that we are getting some compilation error why are we getting some compilation error but it is because if we are implementing something we need to override all those methods that is present in the user details so I have written this user details and uh I'll come to this get authorities later for the username as I told earlier I want to use it as email so I need to written the email and for the is account non-expired is account expired true non-expired will be false okay true then what do I need to do is account nonlocked same thing true my account is not locked is credentials non-expired no and is Boolean is enabled true so I have I have set all the properties if you see here these are like opposites is account locked should be true should be false since this is is account nonlocked it should be true this is like uh this this is like little different and for the authorities what I have did is I have created one enum called as role so what are the uh what are the uh members who are the members of my application so for my application I have defined only two role for this demo one is member and the other one is admin so member will have uh if if suppose I have a member role I will be able to access all the apis of member apis if I have some some admin role then I will be able to access some admin related apas I will show show it in the demo don't worry for now just try to understand that we have an enim called role and in that enum we have provided two values member and admin these are the two roles that we are going to follow in our application these are the authorities that I'm going to use in my JWT token so this is the role so if we see this get authorities method we can observe that this is returning a collection of granted Authority so for us the roles that we need need to define or is going to be the granted authorities but we need to return a collection of granted authorities and if I go to this granted Authority and if I see the implementation for this we are able to see three implementations for that one is jazz granted Authority second is simple granted Authority and the third one is switch user granted Authority we are going to use Simple granted Authority in our application so what I'm going to do is I'm going to return a list Dot off because we need to return the collection and the collection that I'm going to use is list and I'm going to return the simple granted Authority as I told earlier so this is my simple granted Authority and this simple granted Authority if you see this is accepting a role of type string yes I have defined a role and I'm going to pass that role here I'm just going to pass the role do name here so it's as simple as that get authorities method is a collection of granted Authority and this simple granted Authority is a implementation class for this granted Authority that we are going to use so I'm creating a new simple granted authority of type roll and I am returning that in a list as simple as that so we are now created our user class as I told earlier we are finishing all the stuffs related to this user first so I have created my user class all well and good then what do I need to do I need to create a user repository so as I told earlier I'm going to use my email so what I did is I have have created a repository okay I missed to add at repository annotation I'll add it so we have created a user repository and that is extending my jpa repository so jpa since if you remember we have added spring data jpa dependency with is because we are using jpa repository so my user repository is extending this jpa repository and I need to provide the class name and the uh uh data type of my uh entity here so my data type of my entity is here is integer and that is why I have provided integer and this is the entity type so in this repository I'm use I'm going to use this user entity and this is my data type of my ID and here I I have defined one method which is nothing but find my email only if I provide like this it is enough because it is because I'm using jpa repos and jpa will write uh jpa will return me the uh user with the sending email ID with the specified email ID so all good I have written my you repository as well so everything related to my user got over I have created my repository I have created my role I have created my user class everything related to user is got completed for now I've done everything related to user meaning I have created an user entity I have created a user repository so if I created that then what I'm going to do next then I'm going to create an endpoint which is nothing but the register endpoint which is used to register my user so what are we going to do we are now going to create an unsecured endpoint which is nothing but the slash register which is used for the user registration that is what we are going to create now so we are going to create a endpoint which is nothing but slash register in our application so for that what I have did is I have created a new package called o and inside that package I have all my I have added all my required classes so if you see here this is my o controller to let spring know that this is my controller class I have added at rest controller annotation and I have provided a URL for it for that and this is my at request mapping and inside that I have provided the URL for the specific controller and I have added at required a Constructor to uh to do the Constructor dependency injection for this o service so all well and good my mapping actual my register APA endpoint is coming here and this is a post mapping why this is a post mapping it is because we are creating a user so we are registering a user we are creating a user so if we are creating something then we need to use at post mapping annotation at post mapping HTTP method in the rest API that is why we are using at post mapping so as a in the body of the request if you see we are sending something so if we are sending something in the body post mapping body then we need to provide that in this at request body annotation that is the reason I have provided this is at request body annotation and we are sending a request and if we see the my request is nothing but nothing fancy first name last name email password and Rule so if if I'm going to register as a user I need to provide my first name last name my email ID and the password which I going to use for this spe to log to this specific cracket application or Spring Security application or whatever it is to log to this cracket application I need to provide a password and that password and what are the roles so uh usually this will be done by admin let's assume so what are the roles that will be allocated to that user as I uh as I explained in the slides for our application we have two roles one is member role and the another one is admin role so to which role this user belongs to all this information will come under this register request so I'm passing all that information to register my user so once the user is registered let's assume the user is registered what do we need to return to the user we need to provide the user with the access token which is nothing but the JWT token so with that JW token only he will be able to access our other endpoints which we are going to create either with the admin role or with the uh member role so once the user is registered we are going to return the user with an access token which is nothing but the JWT token so let's see what we have written in the code for this in the uh AU servers so we didn't finish this yet let me explain what we have have till now so what we need to do we need to save this user this request object to my user entity so that is why we have created our user entity yes I need to map all the information in this register request to my user entity and I need to save that user object to my database so let's let's map all the fields so if you see here in the register request we have first name I mapping that first name to my user using the Builder so user do Builder builder of first name first name from the register request last name last name from the register request similarly for the other things as well so we are well and good I have mapped my my uh dto with my entity object so what do what do I need to do next I need to save the user to my database to save the user to my database I'm using we have already created this user repository since this is extending the J jpa repository by default it will have the save method so but I'm using that save method of the jpa repository and I am saving this user entity to my user table so all well and good by already written my entity and my entity and the table name is underscore user so all this information will get saved to the user database and then what do I need to return I need to return the user with the JWT token let's now see how we are going to write the implementation for that creating the JWT token and returning it to the user to create a JWT token or to validate the JWT token so if we are using JWT in our spring boot application we need to make sure that we need to add these three dependencies in in your code so I have added these three dependencies JJ WT API and JJ WT IML and jjw WT Jackson since we are going to create a JWT token we need to add these three dependencies in our application so I have added these three dependencies then I have created one service called as the JWT service if you remember when I was explaining the flow I told you that we will validate the user or we will create the user using this JWT service so in this JWT service I I'll come to this later so in our service we saved the US user then what do we need to do we need to generate the token and we need to send that token to our user so to generate a token only I have created this JWT service and I have annotated that class with at service annotation because I'm going to maintain this as a service and I'm letting my spring know that this is a service and I am I am creating so only if we add this annotation during component scanning it will identify this as a uh service class so all well and good so this is the generate token method If You observe closely you can see that this generate token method is accepting user details what is this user details this user details is the interface from the Spring Security framework we already uh if you remember we already implemented this user details in our user entity object so no problem it will accept that user object for this method so if we send our user object you can see that we are getting user do get username but in our user entity we don't have anything called as username so we need to map our user entity object order like we need to map which specific field we are going to use as a user name so in our application we are going to map the email as the username so this part is pending I'll let you know I I'll let you know or we will do it in few seconds we will map the our email ID in this user entity object to the username field this is spending we will do it in another 2 minutes so otherwise if you see here we are using something called as JW TS what is this JW TS this JW TS if you see here it is coming from the maven dependency that we have added which is nothing but the Json web token so spring that uh the dependency that we added is has lots of benefits that that dependency itself will help us to create or generate our JWT token so with the help of the dependency that we added it's straightforward and simple if we write code for this J WTS do Builder off we can map all the fields and we can create the JWT token that's it so JWT is Builder do subject we are setting the subject as our email ID this part we will do it later and issue that issue that I'm passing the current time stamp because we are going to issuing the token now and the expiration expiration date I have I have added some value to it so it will be valid for one day this is in milliseconds so this is the this is the value that is equivalent to the milliseconds for one day so this token that I'm generating will be valid for me one day so I'm setting the expiration date as current milliseconds plus one day so it will be valid tomorrow uh till the same time tomorrow and we need to sign the key if you remember when we were discussing the JWT token uh video we have clearly explained each and everything what it is so we need to sign that with a uh with a key so for now I'm just using a secret in my application but in the realtime production applications either that will be a public and those secret will be available in the AWS if you're using AWS that will be available somewhere in your Cloud environment it will not be it will not be easy as as we see now so I'm using some secret and with that secret I'm signing my key so I'll I'll come to that part and if I give do compact method my JWT token will get generated so JWT token can be generated easily using the maven dependency that we have added so it's simple J WTS Builder dot sorry j WTS do builder of subject issued at expiration sign with and compact so for signing we need to send the key and the algorithm so what is the key that I'm going to use that will be my secret key and on on basis of which algorithm I'm going to sign the key so for that what I did for what is the first parameter my first parameter is the secret so for the key what I'm doing is I'm taking the secret that I have provided here so I I'm using uh decoders dobas 64. decod of secret which will return me The Bite array of key bytes then what I'm doing is we need to send as a key so we need to send it as the key so to convert my secret to the key what did I do keys do hmac shocky for I'm using it and I'm sending the key bites so it's very simple if I have if we have some secret and if we need to convert that secret to the Keys we need to use keys. hmx shock ke off like in case we have like uh other algorithms as well I'm using hmx shaki so hmx shaki of if5 sent the key bites it will convert me convert my secret into the key yes all well and good I have my key then I need to pass my algorithm I'm using HS 256 algorithm you can use whatever algorithm you want to use so this is easy that is why I'm using this hs256 algorithm that's it we have created our JWT token so if we look closely this decoders and these key both are coming from the Json web token Library only it is it is because of the mayand dependency that we added so everything everything all those we required to create a JWT all are present in this Json web token artifact that we have added so all well and good we have created our key we have generated our JWT token and we need to return that JWT token to our controller class so let's see what we are doing we have something called as authentication response this is the response that we are going to written to the client so this authentication response has something called as access token and we have said the Json property as access token so in Postman if we see it will display as accessor token so we are setting that JWT token to our authentication response so authentication response. builder. access token off we are setting the JWT token that we generated here in this JWT service and we are building it and we are returning that so it is basically a string this JWT token is a string and we are returning that as a access token to the user so once the user is registered to application we are saving that user and we are returning the user with a JWT token so we have created our authentication response and let's return that authentication response to our controller so from the controller what are we doing so we are we got the response that we that we uh created using this authentication Service and we are returning that response with with response entity. off we are passing this Au response as a body all well and good let's start the application and let's now check whether our application is working fine or not when we use Postman so I have framed my Postman request so if you see here this is the end point so my Local Host is running in the port 8080 and this is My URL SL cracket slv1 sl/ register so and I am passing the request body as well as as we know the request body is first name last name email password androll so I have set everything I and if I let's check whether this is working fine or not if I click Send we can see that we are getting status 401 and authorized so why are we getting this as status 401 and authorized so we just we uh in this video we told that if we just add that Spring Security dependency to our application all our end points will get secured so what do I need to do I need to Whit list this specific API I need to let uh Spring Security know that I want to whitelist this API I want to unsecure this API I don't want uh the Spring Security to secure this end point so I need to let the FR spring framework know that I don't want to secure that end point that part we didn't do that is the reason it that is the reason we are getting 401 unauthorized let's add that part so to enable my request what I have did I have added a configuration class under my config package so which is nothing but I have added security configuration class in the config package then what do we need to do we need to write a configuration class so if I write if I write a class with a configuration annotation then it's obvious that I will use at beans I will create my beans in inside this class so also I if you closely look I I have used at enable web security annotation as well let's go to that annotation and let's see what is written there so if this at enable web security annotation should be used along with the at configuration annotation why are we using it because we are defining something in our Spring Security configuration so we are adding something to the our Spring Security filter chain and if we need to add that to our Spring Security filter chain then we need to use this at enable web security annotation also if you see I've just copy pasted the code from here only to overwrite the Spring Security filter chain what do we need to do it's it's the the spring framework has provided it we need to just copy this code and paste it over there so what do I do for now we didn't Implement role implementation and all that is why I didn't include it future in this video I will add all these but for now what do we need to do so we need to just add this to our code so I have already added it I have copy pasted that from this at enable web security annotation here this from here only so after I copy pasted what I did this so for my request if my request is having a pattern which is nothing but SL cracket / V1 sl/ register please permit that request for all the other request you you need to authenticate it it's like very simple so if my request is matching this pattern please don't secure that endpoint and for all the other requests secure that endpoint authenticate that endpoint that's it it's very simple even for this what do you need tonight don't get confused go check here you you'll you can see everything here even I have copy pasted this from here and you can see that if my request is matching SL cracket SL slv1 sl/ register so if you see that I want to Whit list this register endpoint and that is the reason I have provided if my request is matching this please whitelist it please don't authenticate it please don't secure it and for all the other requests please secure it let's start the application now and check whether this is working from Postman or not so let's try from Postman and you can see that our request is working now why because we have Whit listed API and that is why it's working now so all well and good when we send our request body with first name email last name password and our role we can see that we are getting a access token so this access token we can we can this access token is a JWT token so what I'll do is I'll go to JWT IO and I'll open this token I'll show you as well so I've just copy pasted that jwd token from my Postman to this JWT iio so if we do decode it we can see that we have used HS 256 algorithm yes if you remember in the code we have used hs256 algorithm and in the subject you can see that we are getting the email which is nothing but cracket te talks gmail.com and it is issued at Tuesday uh you can see the date and you can see the expiry As One Day More so March 19 1057 to March 20 1057 it is valid because if you remember in our code we have added one day uh to our issued time as the expiration date and we have a signature as well so all well and good our uh JWT token has been created now so we didn't add role information and all to our JWT token it we will add it further as we proceed in the code I'll show that part as well we are now going to set the claims in our jwd token so if you see here we didn't set claims here at all there are two ways in which we can set claims one is like you if you see we have a method called set claims here which will accept the claims and that will take the claims and one more thing if you see here we have we can set claims using a map with a key and a value key as a string and if you have just one claim if you want to just set one claim you can use this claim method for now I'm going to add the authorities only so what I'm doing is so I will add this authorities here and to populate the authorities to my claims I'll just add add a method here so and I'll paste this authorities here so from where are we going to get this authorities we will have this authorities in our user object which is nothing but user. getet authorities yes I'm going to send that user. getet authorities to my populate authorities method so what I'm doing here I'm just iterating the authorities that is coming from my request and I am setting that and I am adding that to a set why am I adding that to a set because even if by mistake if my request has uh we have two roles right if my request has member comma member I don't want that duplicate that is the reason I'm adding it to a set so after adding it to a set we are adding we are joining all those elements in the set with the comma so why are we joining it because authorities is a single claim and that claim method if you see it is going to accept a string as a uh variable one variable and that is authorities and here can be any of object the object that I'm going to use is again a string so what I'm going to do I'm going to accept my authorities by comma separated if I if suppose I'm sending member and admin I I'm going to send my authorities I'm going to set my authorities like this member comma admin so for that what did I do I'm adding sorry I'm joining all the elements in my set by comma using this string do join method so it is as simple as that we have set my claims as well let's now check uh start the application and check whether we are able to get this claim as a part of the JWT token so this is my Postman and I sending my request now and I'm going to take this access token and I'm going to paste it in JWT IO and we are going to check whether this is going to work or not so for that I'll sorry I'll open this JWT IO and let me paste the token here so you can see that we can see see one more claim called authorities and that authorities is member now so because in our request we pass this member as a in this uh in our request we passed this member as a role and we are now able to see that member in this JWT token so all well and good let's now our registration is successful so I have developed my cracket application and I am new to that cracket application I don't have I don't have any user credentials for it so so what did I do I registered myself as a user and I have a token now so all well and good I now registered to my uh cracket application so I'm coming tomorrow so with tomorrow let's assume my JWT token will not be valid so what do I need to do I need to log to the cracket application I need to get the JWT token and then only I will be able to access the other endpoints if I want to access either as an admin or as a member or whichever who whoever am I is so I'm coming the next day to by by the time I cannot use this register endpoint why because I'm registered already so what do I need to do we are now going to implement this authenticate endpoint what is this authenticate endpoint this authenticate endpoint is going to accept username password it will check whether my username password is present or not if my user is valid or not all those information it will check and if everything is valid it will it is going to return me a JWT token and with that token I will be able to log to the apis that whichever I want want to access so let's create this authenticate endpoint now let's now authenticate the user for authenticating the user if you look closely we have added an authentication request so what is my authentication request authentication request will be as simple as that it will be just the email and the password so it's just the email and the password that we have added yes if you're logging into the application you are already registered yourself if you are logging into the application you will just provide the username and password to that application so that is that is our request which is nothing but email and password so before we before we start writing code for the authenticate method I just want to change one thing in the register user which is nothing but if you see here we are saving the password as the plain password in the database so it is not a good practice to save the password a clear text password is a clear text in the database so what do we need to do we need to encrypt the password and we need to save it in the database so to uh to perform that encryption what I'm going to do is I'm going to add a uh configuration class and that will do those things for me that will encrypt the password for me so for that what I did is I have added a configuration class so inside my configuration I'm going to add a bean which is nothing but the config Bean to me so which sorry which is nothing but the password encoder Bean to me so what I'm going to do is I'm going to add a bean here and that bean is nothing but uh password [Music] encoder okay so password encoder and what password encoding I'm going to do I'm going to uh do a bcrypt uh password encoding so what I'll do is bcrypt password encoder so what I'm doing I'm not going to save my password as a clear text instead I'm going to save my password as a encrypted password and for that encryption we are like the Spring Security is providing a few uh few things so few crypto things so I'm going to reuse the same password encoder that Spring Security giving it to me so what I'm doing I'm going to encode my password always I'm not going to save my password at all so we have just added this password encoder so using this password encoder what I'm going to do is so password encoder and I'm going to use this password encoder and I'm going to save uh encrypt my password so now I'm after this I will not save my password as a clear text my password is encoded all well and good it's very simple we have just added a password encoder in our application and Spring Security provides few ways and I'm using one of those ways which is nothing but bcrypt password encoding so I have encoded to so I have created a bean for the password encoder and I'm just injecting that password encoder Bean to my OD servers and I encoded my password let's start writing the code for this authenticate uh API so for that we already uh see what we had in the request and in the response what we had is nothing but the access token yes we are going to validate the credentials that the user is sending and if the credentials are valid we are going to send them a JWT to toen so what are we going to do in this authenticate request we are going to validate the username and the password so for that first what are we going to do we need to check whether our user is present in the database or not if it is present in the database then it's well and good we will proceed to the next step if it is not present in the database then we are going to throw an exception to the user saying that user not present in the database so as you remember we are storing our user information in our database so our authentication provider that we are going to use in our uh Spring Security JWT implementation is Dao authentication provider so what is the authentication provider that we are going to use it is nothing but the Dao authentication provider why are we using da authentication provider it is because we are storing the user credentials in the database then what do we need to do we need to inject uh this authentication provider to this authentication manager meaning we need to let authentication manager that we are using this Dao authentication provider all this we are going to do now so what where are we going to do we are going to do this in the application config file so in the application config file I'm going to add something which is nothing but adding this authentication provider so what is my authentication provider as I told earlier the authentication provider that we are going to use is the Dao authentication provider and in the Dao authentication provider if we are going to overrided we need to set the user details service do we know what our user details Services yes we know our user details service so what is this user details service this user details Service uh okay as I told earlier we are going to throw an exception which is nothing but the user not found exception to the user if the user is not present in the database so which is our uh database which is nothing but the user repository so user repository is my database and I am going to use this user repository class I'm going to validate my username I'll add a requir o Constructor yes I'm going to validate my user whether that user is present in this user repository or not if it is not present then I will throw user saying that username not found exception so when we are writing the code for user repository itself we already wrote the code for find by email so I'm I'm going to use that method only so the username that I'm going to use is the email ID so that is why I have provided find my email method if it is present please use that username if it is not present throw an exception saying that username not found exception with uh message as user not found all well and good and we need to use this user details to the DA authentication provider why are we using it because only if we if we Define that be here then and only that validation will happen so let's come here we what did we do we verified whether the user is present in the database or not yes the user is present okay if the user is not present in the database you we thrown the exception if the user is present in the database we need to encode the password that is coming from the request so the user will will will will not enter the encoded password but we need to encode the password because we stored the password as the encoded password in the database so we need to encode the password before it goes to the authentication manager so what did we do we have added this password encoder as well to our Au provider we already defined this pass uh password encoder in our application config I'm just reusing that here so my authentication provider is now ready what is the next step we need to Define our authentication manager so what is my authentication manager it is very simple just use the configuration like uh just use the authentication manager that is present in the config it's it's very simple nothing no fancy code it's easy so we have implemented everything so we have defined our user details service and in the user details service we are verifying whether the username is present in the database if it is not present in the database we are throwing an exception and we are using this user details service in our authentication provider and the authentication provider that we are using is Dao authentication provider since the password is the coming in is the clear text we need to encode the password before we sending it to for the validation or for the validation so we have encoded the password using this Au provider and we need to inject this Au provider to the authentication manager so we are just informed that like please use the authentication manager in this configuration it's like very simple if you understand the steps and if you know what you need to do it's not complex we have done all these steps we have created everything required for the authentication so let's start the authentication now so how are we going to authenticate we are going to authenticate it using the authentication manager do authenticate method so let's let's first inject that authentication manager here so for that I'll use uh I'll inject the authentication manager that we have created so we have created our authentication manager and I'm going to inject that authentication manager and uh we are going to use that Authentication manager to authenticate our object so for that what do we need to do so we have a method called authenticate in the authenticate manager and for that we need to send the authentication object so for which authentication object we are using which is nothing but the username password authentication token so if you see here this username password authentication token is extending this abstract authentication token and this abstract authentication token is implementing authentication so we need to send the authentication object here and that authentication object that I'm using is username password authentication token and you can see that it's like very easy why are we using this authentication one minute let me open this yeah if you see here you can see that this is nothing but the principle which is nothing but the username and the credentials password should be set within an object that provides the respective property so we need to written an authentication Pro object and for that object we need to save the user name and the password and to use return that authentication object so when we were discussing about Spring Security we told that this authentication provider or the Spring Security filter chain will return as the authentication object that authentication object is nothing but the username password authentication token that we are using here so all well and good and there's no need for us to explicitly write code to match to check whether the username and password is matching with the database or not why that is not requ because we spring is doing everything for us we already mentioned that we are using Dao authentication provider and we injected that to our authentication manager and if we do authenticate this authentication manager will will handle that part for us which part it will check whether the username and the password is matching with the database or not that is confirmed that that is all done so and if you see here this authenticate method is throwing authentication exception if it is not matching then this will throw authentication exception to us till now we have verified whether our username and password is matching with the database or not yes it is matching and if it is not matching we are throwing the exception as well so what do we need to do so my I have verified my user credentials and that looks fine to me then I need to generate the user token so to we we are going to reuse the same method so to generate the jw2 token what do I need I need the user details object are we going to fetch the user object so I have my email so with that email I can fetch the user details from my user repository so since we have find by email method so I'm going to use that method and I'm going to fetch the user information I have my user information now and I'm going to generate the token it's very easy as we did already we have written the code for that I'm going to just reuse that so I have generated a token which is nothing but the JWT token using this JWT service do generate token off so it will work for me and what do we need to do written we need to written the auth authentication response from here so the same thing so I've just copy paste this code so I'm going to return this authentication object sorry uh authentication response okay I think I have made a little mistake so what will I do is I'll go to my here and I need to give it as response entity. off and I need to call that method that's why so I'll change it and I'll go inside this method and I'll just delete this this will work fine for me so all well and good we have written our code so what and all we did in this authenticate method we just defined that we are going to use Dao authentication provider we have create we have injected that Dao authentication provider to the authentication manager we verified whether the username and password is valid or not if it is valid we are generating the JWT token and we are returning that JWT token it's simp we are returning the access token to the user so let's start the application and check whether this is working or not so we forgot to add one more thing which is nothing but whitelisting our uh endpoint so if you remember previously we have Whit listed only the register endpoint now I want to Whit list my authenticate end point as well so what I'm doing is I'm just putting a star here so what will the star do so if anything comes after o slash please whitelist all those URLs so I'm I'm complete completely Whit listing all the end points that is present in that is present inside my authentication controller so I'll open the authentication controller yes if you see here this is this is my cracket uh V1 o so I'm completely wh listing all the end points inside this o controller so to do that what did I do it's very simple I have just uh put a start in I have removed the register which was present already and I have just put a start this will Whit list my authenticate and register end points so let's now start the application and try I've just hit my uh register endpoint and you can see that I have saved a user and the user's email is cracket Tey talks.com first name last name and now you can see that the password is encrypted why this password is encrypted it is because we have used passcode encoder in password encoder in our application and I have defined the role as member so I have created a user and let's try to authenticate this user now so for that I'll go to postman so in this Postman if you see we have already registered the user with cracket as cracket Tey talks as email and the password as test so we are now going to authenticate the user so for authenticating the user we need to provide the email and the password as the request body so I'm providing the same password that I've used here which is nothing but the test and if let's try to test our method that we written so it's getting forbidden so we have got the status as forbidden so we need to analyze why we are getting forbidden for that I have added this logging level which is nothing but logging level or spring security framework sorry or spring framework security to trace so I want to know what is happening in inside my filter chains so to see that I have enabled that Trace level so I have enabled my logging level for this specific Spring Security package to trace so it will print all the loggers so let's start the application now and let's try hitting it again and let's see what happens so for now I'll clear it I'll go to my Postman so I'll go to my sorry Postman what I'll do is I'll first register no problem then I'll authenticate so for authentication we got it as 403 Forbidden so let's analyze the logs why we are getting that 403 Forbidden so only if we enable this logging level we will be able to see all this else we will not be able to see so we can see that we are getting an exception here and that is nothing but no default Constructor for entity user okay okay we forgot to add uh default Constructor for entity user entity object it seems so I'll go to my user object yes I have just added allog Constructor we need to add no Constructor as well so I've added it I'll stop it I'll start it again and let's see what happen happens now I'll go to my Postman let's first register the user then let's authenticate the user yes now we are able to generate the access token so it is because previously I didn't add the default Constructor for uh the user object that is why it was throwing the exception but to see the logs what is happening there we need to add this logging level that I have just showed which is nothing but logging level uh Trace we have enabled the trace logs for this or spring framework security why did we uh added this it is because we need to know what is happening inside the security filter chain if we didn't add that lock we won't be able to see that so for now everything is good all all good we have created the access token we can see this access token in JWT iio as welled the token here and you can see that the subject is cracket Tey talks.com authorities and all it has fetched it from the database and uh it is showing the issued it and the expiration time all the information that we set in the JWT token so we are now able to authenticate the user as well since we created the user for member let's now create an endpoint which is nothing but slash member read that is that should be accessible only for the uh users who has the authorities as member let's try to implement this slash member read endpoint now let's compare with the code flow on what we did till now so what we did is like we when a request sent it will check whether the it is a wh listed URL if it is a wh listed URL it will route the router to the corresponding controller and we will get the response so this part we have completed now what are we going to do we are going to implement a member controller or an admin controller which is a secured endpoint so if it is a secured endpoint what do we need to do first of all we need to create a JWT o filter and in the JWT o filter we need to do the user validation we need to use you we need to do the JWT validation and if the JWT is valid we need to store the principle in the security context holder and then we need to hand over the request to the controller so it involves three steps and those three steps should be present in the JWT o filter so what are we now going to do before creating the controller before creating the controller we are going to create a filter which is nothing but the JWT o filter let's start with that process now so we are going to implement the JWT author for that I have created a JWT o filter inside the config folder and I have added at component annotation to it and what I'm going to do is I'm going to extend something called as once per request filter so what is this once per request filter so if we see the uh if we see what it is written it is for each and every every request so what the the this filter will get executed for each and every request so when a request Comes This filter will get executed for each of the request that you sent the if this filter will get executed it is because for each of the API that we are going to call that we consider as a request and those all request needs to be validated or that all request should be validated or that all request should be authorized for that reason we have added this JWT o filter and we have uh made this JWT o filter to extend this once per request filter so after extending you can see that there is a compilation error which means I need to implement the method so uh let me do one thing yeah I need to implement this method so you can see that there is some uh uh what is it the it is showing some warnings so just to avoid those warnings I I'm adding this at not null annotation to all my request response and the filter chain yes all well and good my request response and filter chain everything there are no warnings so I have to implement this do in do filter internal since I am extending once per request filter so what are we going to do now so what are we going to do is we we are going to verify whether this is a whitelisted path or not if this is a whitelisted URL I don't want to execute this filter it is because for us the wh listed endpoints are authenticate and um and registration so for both of the authenticate and the registration end points I don't want this filter to be executed so what I'm going to do so inside this once per request filter we have something called a should not filter so what will the should not filter do if I overwrite this method it will not execute this JWT o filter for the specified uh whatever we specifi inside that should not filter so what I'm going to do is I'm going to add override this should not filter so I'll copy paste this code here and here what I'm going to do is same at not null yes so what what are we going to filter so we we are if my request do get serlet path so I'm going to take my request and if my request. seret path contains of Slash cracket SL o SL sorry SL cracket slv1 SL then then please don't use this JWT o filter we have made our entire o controller as a unsecured controller so that is why we have added that o controller path here so if our path if we have a path which doesn't want to execute this filter we need need to provide that path here so for this specific path if we override should not filter our JWT filter or filter which we write here will not get executed so first step is done so the main purpose of using this JWT or filter is to validate our JWT token so if we are going to validate our JWT token where will we have the JWT token we will have the JWT token in our request as a part of our request header so in our request header we will have have something called as authorization and in that authorization only we will be sending our JWT token so I hope you know this so that is why verify whether request has authorization header or not that is what we are going to do now so this is our second step what is the second step if I get a request and that request needs to execute this JWT Au filter I'm going to verify whether my request has a header called as authorization so I'm getting that value what it has and if that value is suppose null so which means it doesn't have any value in the authorization uh header or if it has authorization and if it is not starting with beer space so wherever we use jwd token we will send that token with uh as beer space the token only so if suppose it is not starting with beer space then what do we need to do it's very simple don't execute the rest of the path written go and continue executing other security filter chains that is available you have nothing to do in this JWT or filter that's what we are trying to say I'll just copy paste this here because this is where we did that part and we have finished checking whether our authorization header has beer value if suppose that beer value is not present please you can continue executing the other filter chain we have done with it what is the next step we need to extract the token that is present in the header and then we need to validate that token so what are we going to do we we are going to extract the token so extract the user from the token okay I'll mention it as exact the JWT from the authorization header that is what we are going to do so for that what are we going to do is it's very simple I'm going to uh create a string called as JWT and to that string what are we doing I'm getting this Auer and do substring of begin index 7 why am I uh why did I give seven it is because bror is six characters and one space we will give and after that space only we will provide the token so we we are getting the token we are actually extracting the token from this authorization header I'm removing this beer space and I am taking the token so I have my JWT token now so what do I need to do I need to verify whether my token is valid or not so to verify whether my token is present or not first I need to check whether there is no authentication or object in the security context so for that what I'm doing is I'm going to uh check whether my uh whether my authentication object is not present in the security context so for that what I'm doing is so I'm I'm doing checking whether my security context holder. get context. get authentication object is null then only we have to do all these steps why if if suppose a if suppose a JWT authentication happens it will store that to the authent uh uh security context object only if it is not present I need to execute this filter so yes it is present it is not present in the security context then what do we need to do we need to Pro validate the JWT token so let's start with the validation step steps to verify whether the user is present in the database and to verify whether the token is valid we are going to write a method in the JWT service so I don't want to waste my uh I don't want to I want my code to be clean in the JWT o filter and since this is is related to the JWT token I moving that code to the JWT service so first of all if I have a token I need to extract all the claims that is present in the token that is what I need to do first so if I have a token and if I pass that token then I need to extract all the claims only if I extract all the claims then only I'll be able to get the subject and if I get the subject I I can I can uh check whether that email ID is present in the data database or not so even for that what do we need to do we need to extract the claims that is present in the token so I have written a method which is nothing but extract all claims and the and we have something in the J WTS which is nothing but the parcel Builder so this J WTS dop parser Builder will pass this token and it will return all the claims to us and the claims will be in the body and that is why we have provided it as claims otherwise will be uh so all these the P claims will be present in the body and that is the reason we are returning the body so J WTSP Builder do set signing key we need to say provide this key okay yeah uh because we need to use the same secret that we have used to create our JWT token so to generate my token I have used some key I need I have I have used some key I have to use the same key while extracting the claim as well so I'm using the same token and I'm uh using this J WTSP parser method I I am now able to get all the claims that is present in my token all well and good I have taken all my claims then what do I need to do so also if you see here this parser okay 1 minute yeah pars claims JW tws method if you look closely this method is throwing expired JWT exception unsupported JWT exception malformed JWT exception and illegal argument exception if suppose my JWT token is expired the SP claims jws is itself will throw me an exception saying that your JW token is expired so my expiration will will is all already included in this pass claims but even if I want to verify it again yes well and good we can verify it not an issue but I just want to let you know that the parse claims method is already verifying the verifying my JWT token for the expiration date so also the same pass claim method will throw signature exception if there is any signature mismatch or if if if my JWT token is tampered in the middle for all those as well it will throw the signature exception so anything like this parser Builder or this parse claims jws will validate the my JWT token for expiration dates for Signature and for everything even if we you want to override the uh expiration date yes we can do it I'm just letting you know that this parse claims method will throw all the required exceptions it will validate my J to jot token and it will throw the exceptions so my claims is ready and from my claims what am I going to do I'm going to extract the user so why am I going to extract the subject it is because I'm going to verify that email ID is present in my token or not so when we generated our token we have set the uh we have set our username in this subject so we are going to extract this subject claim from the JWT token and we are going to verify whether that uh subject is present in the database or not this is also one of the validations that we are going to do now so I have just added this if you see here we are going to extract this this email from the token we are passing the token and we are going to extract whether our username like we are extracting the username from the token why are we extracting it from the token only then we can verify whether it is present in the database or not so for that what are we doing we are extracting the username from the token so what I'm going to do is I'm going to uh I'm going to write that in my JWT Service as usual I don't want to do it here so I'm going to write it in my JWT service so for that I'm going to add this uh what is it yeah add that JWT service here and I'm going to add required Ox Constructor so I have added it all well and good so I have added this method as well extract username in my JWT service so to extract the username what are we doing since we are doing it before a step since we are doing it before this if block I'm sending it as uh I'm sending my JWT token so with the JWT token what I'm going to do I'm going to extract my username so how am I going to extract my username I have passed the token and we have a method called as extract claim this method also I have written just now so if you see here inside this extract claim we are calling this extract all claims method we just discussed so this extract claims method will have all these claims so this extract all claims method will written all the claims and in the claims what I want I need just the subject why I just need the subject because I want to uh extract the username only so the username is subject in my my uh in my claim so what I'm doing I'm extracting all the claims from the token and from those claims I'm resolving just this get subject so that is what we are going to we are doing it here so how am I extracting my username it's all well and simple I'm sending the token and I'm sending that token to this extract all claims method this extract all claims method will extract all the claims that is available and in those all the claims I'm just resolving this subject claim that's it so we now have the extract username so only if it it may be this email may be null if if in my jwd token if the email is not set if the subject is not set I may get null as well so if I'm changing this condition to if my email is not equals null and if my security context uh security context holder. getet context doget authentication equals equals what is it so in my security context there is no authentication object which means there is no authentication happened before this is the first time it is happening so please do all the validations that you want to perform so also if you note here in this extract user name itself we have validated our JWT token as well because we are using parse claims uh jws so this will in turn validate all these things it will in turn throw signature exception if there is any if my jwd token is tampered if it is expired so it will throw all those exception but even if if I want to validate one more thing like if I want to validate whether my jwd token is not expired or not I want to do one more level of validation yes I can do but for now in this example I am not doing it but if you want to do it you can always do it so we have extracted our username we have verified our JWT token so all this we have set it even before this so we have completed all these steps here now going to verify whether the user is present in the database or not so for that do I need to do am I going to write a separate repository and check whether my user is present in the database or not no that is not the case I'm going to use spring Securities user details service so if you remember our user uh our user entity is implementing this user details service so since my entity is implementing this user details service already my Spring Security Frameworks provide me an interface which is nothing but the user details interface and in that interface we have a method called as load user by username so I'm going to reuse this username uh load user by username it is because even uh even if that username is pro not present in the database it will throw user not found exception so it's no need for me to write explicitly code for finding user by username spring provides that uh method for me so I'm just going to reuse it so for that I have just uh injected this user details service and I am going to use that user Detail Service and I'm going to fetch that object so I'm going to pass the email that I have and passing that email I'm I will get this user details object if this user details object is null what does that mean it means that my entity my uh like my my I don't have a user with that username so that is not a valid scenario we need to throw the exception will that happen yes that will happen automatically here itself username not found exception will get thrown so in our JWT o filter we have completed all the steps except the storing the information in the security holder so whether we verified whether the user information is present in the database or not yes we did we verified whether that is a valid user or not and uh we have thrown the corresponding exception as well so if the user is not valid we are throwing the user not found exception and we are reusing the spring Securities user details service all well and good everything related to user is done next comes the JWT whether we verified whether our JWT token is valid or not yes we verify uh we verified our JWT token how did we verify it we have a pass claims JMS method while retriving the CLS we have validated our JWT token as well for that we are using JWT odd service yes till this part everything is over don't get confused have this flow in your mind and then start coding then everything will be easy for you so what we what do we need to do next then we need to store our principal in the security context holder yes let's do that now we have a valid token now how is our token valid we verified whether the user is present in the database or not we verified whether our all our claims are matching or not all everything we did so my token is valid so if I come to this part my token is valid so what I'm going to do now I'm going to create an authentication object and I need to store that authentication object to my security context holder this is my last step so to create the authentication token what what am I using I'm using username password authentication token yes it is because we are using the Evo authentication provider and we have saved the username and the password in the database we are using this username password authentication token so if you see here this username password authentication token is extending abstract authentication token and it is implementing the authentication object so we are using this username password authentication token to create our authentication object so what are the information that I am passing I'm passing the principal which is nothing but the username I'm passing the credentials for now I will not pass the credentials because I don't want to save my password in my security context holder so I will not pass my credentials then I'm passing the authorities so if you if what are we what are we storing in our authentication object we are storing our username and the authorities and for the credentials I'm passing null it is because I'm don't want to save my credentials to the context holder so all well and good I have created my authentication token it's simple so I will get the context and I will set my authentication object inside my security context holder so it's that's it we have finished everything related to this JWT or filter what and all we did first step we did did this excluding this endpoint so if this is the endpoint it will not execute this filter at all why this is my wh listed endpoint I don't want my Whit listed endpoint to get executed uh uh to be to execute this JWT o filter so I have excluded it what did I do next step next step I have verified whether my request has uh some uh request has a header called authorization and if it is present I am checking whether that authorization header is valid or not if it is not valid I'm uh I'm letting the Spring Security framework to execute the other filter chains available then what are we doing next we are extracting our JWT token from the uh from the header or the from the request so we are done we have extracted our token then what are we doing next we are validating our JWT token then also we are extracting our username and we are verifying whether that username is present in the database or not so my uh which includes the validation of my JWT token so this this uh extract username this extract username if you see this is uh uh this have something called past claims JMS and this will validate my token and I am validating whether the uh subject that is coming from the jwd token is present in my database or not all well and good it is present my token is valid then what I'm going to do I'm going to save my authentication object in my security context holder to save my authentication object in my security context holder I have created the authentication object using the username password authentication token and I'm setting the principal and the authorities I have created the authentication object and I'm setting it that's it so the next step is adding this uh filter chain. do filter of request comma response it is because once our JWT filter gets executed then the Spring Security framework needs to uh needs to execute the other filter chains if it is available so to make that we are giving filter chain. do filter of request comma response yes of JWT o filter gets executed after that what does it needs to do it needs to execute the other filter chains if it is available for that we are adding this line which is nothing but filter chain. do filter of request comma response all well and good next what do we need to do we have created our JWT o filter but we need to add that JWT o filter to our security configuration so how are we going to add I'll show you that as well so before that let it be uh before that I I'll show you one more thing which is nothing but previously we have only this piece of code I'll I'll okay previously we had only this piece of code which is if my request contains SL cracket slv1 SL o please permit for all the other request please authenticate it this one we had even now this will work but one more line I have I have added which is nothing but if my uh if my request contains slash management then that for that specific request please allow roles admin and member so if for the member controller we are going to create I'm going to create my member controller with the request mapping SL cracket SL V1 SL management and that endpoint or that member controller will be accessed by both admin and member that is the reason I have given it here if you do not want that condition in your specific application no need for it is there is no no need for me to add you like this but I wanted to show you this scenario that even for a single controller we can have multiple uh multiple roles associated with it that is the reason I'm showing it so for the for any request which is mapping SL cracket slv1 management which is nothing but a member controller in in my case so I'm going to allow both admin and member to access that controller and this is as usual any for any other requests please authenticate the end points this I I hope this is clear this is the first step that we did like this is not a mandatory step this is based on your application that you're going to create this is the first step second is I I just made my session to be stateless yes it is always good if we uh if we mention it as stateless it is because we don't want our Spring Security context to store anything related to the session that is the reason I have given it as stateless next is authentication provider yes we have created the authentication provider if you remember when we were creating the uh Slash authenticate endpoint we we were creating this authentication provider so where is it just a minute I think it's an application config so if you remember we have created this authentication provider which is nothing but a Dao authentication provider so I want to inject this authentication provider in my security configuration that is the reason I have provided this do Authentication provider next is my JWT filter so where do like where do we need to inject this JWT filter which means we know that Spring Security has lots of filters so in that filters in which order my JWT filter needs to get executed so I want my JWT filter to get executed before this username password authentication filter so if you all well and good everything is ready we have validated our token where did we validate our token in our JWT o filter we have extracted the token and we have validated it I have added the corresponding configurations to my security configuration filter chain as well so what do I need to do next next is creating the controller so first let's see this uh sorry let's see this admin controller it's straightforward so what do I do I have created admin controller and I have created a get mapping so inside that get mapping I don't have anything I've just returning a string which is nothing but secured endpoint get hyphen admin controller and this admin controller will be accessed only by admin that is why I have provided at pre-authorize of has rooll admin so I have created a controller and the request mapping for this control is/ cracket slv1 SL admin and this endpoint will be accessed by anyone who has the role as admin so that is why I have provided at pre-authorized at pre-authorized will will check whether the uh logged in user or the user who is trying to access the endpoint has the role as admin if it is admin it will allow the user to uh it will allow the user to access this method if not it will not allow the user to access this at all so we are all good we are done with our uh secured uh Endo let's start the application and check whether this is working fine or not so I'll authenticate my user yes I have authenticated the user and I'll will take this token and I'll go to the admin endpoint this is my admin endpoint and that is a get mapping so I've given it as get and I provided the URL for that uh admin uh admin controller and I want to provide the authorization header it is because we need we are we are going to use JWT in our token and that is why so if you give if you have you will have a drop down here and if you click it you will have many many so what we are going to use this a barer token so I have given it as beer so if I give beer here there is no need for me to append that b a r e r space it is because by default Postman client will add that so that is why I am adding just my token here and if I send okay you can see that you getting 403 Forbidden let's analyze why we are getting 403 Forbidden so I have debugged the application and find out why that why that issue is happening it is because we didn't add Ro underscore Plus in our get authorities it is always mandatory for us to add role a capital r o l ecore in our Spring Security it is because spring will identify the roles that we provide with role underscore only it will not consider it as only admin it will consider it as roore admin so we need to uh return the authorities with role underscore since I didn't add it I was getting that issue access denied so let me start the application and again and let's check what is happening with the postman now so what I'll do is uh I'll get the JWT token again and I'll try sending the token for the admin endpoint and you can see that we are now able to get the response from the admin controller which is nothing but secured endpoint get admin and controller so our spring application is working fine and we can see that it's it's returning the response from the ad controller so this is what I have so what we can do is we can create one more you okay before that I'll show you the member controller as well so in the member controller if you see I this is just a controller class with at rest controller and um mapping as/ cracket slv1 SL management and we have a method here which is get member and that is a get mapping and that is returning some string if you see here I didn't add any pre-authorized here but here if you see I have added pre-authorized but here I didn't add it is because I have already added who has to access this/ cracket slv1 SL Management in my application config uh sorry security configuration so in my security configuration I have already informed that if my endpoint has/ cracket slv1 SL management please allow both admin and member so let's create a uh let's create a user with member and let's try so what I'll do is in the registration I will uh pass this as a member and I will change the email ID so I will register this user and for this user what I'll do is this is a member user I'm trying to access my uh admin endpoint let's see what happens you can see that I'm getting status 403 Forbidden it is because I don't have meaning the member uh the person with member role doesn't have access to the uh access to admin and that is why we are getting uh 403 Forbidden what I'll do is I'll create quickly one for the member so our member endpoint is/ cracket slv1 SL management I think it's only up to management I'll cross check it yeah it's still management so inside that I have a get mapping and that is accessible to both members and the admin so I've checked it with who is it Ive checked it with member it is working fine what I'll do is I'll I'll get a token for uh admin as well if you remember this cracket Tech talks is for admin and if I provide the admin JWT token it is working fine I'll so we have successfully implemented our cracket application with unsecured end points secured end points for the role admin and for the role member but in the real world the uh the roles will be not that simple it will not be like just admin role and member role so we we will have uh realtime applications wherein we will have admin read admin write admin update admin delete as our authorities our authorities will not be just like admin but it will be like in admin I want I have this read Authority in admin I have this right Authority in member we have member read and member right authorities as well so in that case we need to implement method level security in our application so let's see how we can Implement method level security so it's not that complex since we we came till this part I've made the code changes I'll explain it to you now so we have now we have two roles one is admin and the another one is member so roles is two and for the admin role what are the permissions we have if I if suppose I have admin role what are the permissions I have I have admin read admin create management read and management create so if I have admin role I can have all the four permissions which is nothing but admin read admin create member read and member create if suppose I just have member uh role then I have just two permissions which is member read and member create so previously our get authorities method was uh simple previously what we were doing is we were doing list. off of we have added new simple granted authority of role name to a list now it is not the ISE our get authorities is different so what are we doing we are getting all the permissions so we are getting all these permissions and I am adding it to a list I'm iterating it I am making it as a simple granted Authority and I am collecting it to a list and that's why my authorities now had all the four permissions now I need to add my role so what is my role for role there is a condition as we told earlier that role underscore we need to add the role name what is the role name the role name is nothing but the admin for example if it is admin it is admin so if suppose for my admin role what will be the authorities my authorities will be these four permissions along with the roore admin all well and good I have my role name I have my authorities name my get authorities will get changed what else will get changed in our user uh user entity previously we were using uh okay I'll I'll show you that so in our user entity previously it was it was list. off of the role name now it is not the case since we have implemented this get authorities method here I'm just calling it and using it that's it as simple as that so my now user now my user entity will have these authorities in it so what are those authorities for admin I have four permissions and member I have two permissions these are the code changes then we need to make the code change in the security configuration as well so what is the change in the security configuration so now I have added you know that uh we we already defined that if the role is admin and a member please allow them to access if the request is matching SL cracket slv1 SL management then what are we doing inside that we are adding method level security what is this method level security if if it is a get mapping then allow only admin read and at member read roles and also for the uh post mapping allow only admin create cre and member create uh permissions if suppose I have a JWT token and that JWT token doesn't have uh doesn't have admin read then I won't be it has just admin create then I won't be able to access the get end points that is why we have added this request matches here so what else we need to add I'll show you the uh controllers as well this is our member controller to Our member controller I have just added this post mapping nothing else why nothing else there is no pre-authorized it is because we already defined in our security configuration what has to happen for this management endpoint for the get and the post I'll show you the admin controller so admin controller will uh in the admin controller we have added pre-authorized for the uh post mapping okay where is it so here is the admin controller and here if you see we have added two things which is nothing but for the get mapping we for the get mapping it should have authority admin read for the Post mapping it should have authority admin create so we have added all these let's start the application and let's check whether our code changes are working fine or not with this we have implemented method level security as well so if anyone who has access to role can be able to access this admin controller and if if he has only this Authority which is nothing but admin read then only he will be able to access access this get admin endpoint else he will not be able to access the get admin endpoint if suppose he has admin colon create so we have created or implemented method level security as well with this so let's now verify whether this is working fine or not so I'll just create the user this is for the member so what I'll do is for the member I'll go to the member endpoint I'll copy the so we can see that secured endpoint get is coming and for the Post let's try what's happening yes I'm going to uh access post controller as well so it's it's working fine and for the admin what I'll do is I'll register a user with admin so I'll remove this one and I'll register the user as admin and I've created my access token and I'll copy paste this access token to my admin endpoint admin and point let's see what happens so we can see that this is accessing the uh admin post admin controller let's try accessing get as well it's working fine the admin should have access to members as well so I will change the JWT token and I created and you can see that admin uh what is it admin token is now able to access member as well all well and good we have implemented method security as well in our application by now you should be having a clear understanding of how you can Implement Spring Security in our application how you can Implement class level security how you can implement method level security how you can enable authorization how you can enable role based authorization so by this time you would have know everything about spring security so if you want to discuss any specific topic please let us know in the comment section we are happy to do that and thanks for watching cracket stay tuned for updates please like share comment and subscribe
Info
Channel: crackIT
Views: 14,329
Rating: undefined out of 5
Keywords: Spring Security, Spring Security Crash Course, JWT Authentication, JWT Authorization, Spring Security JWT, Spring Security 3, Role based authorization, authorities based authorization, JWT Authorization filter, Spring Security Filter Chain, Spring security interview questions, for experienced, Spring tutorial, Spring Security tutorial, new in Spring Security, Spring boot 3.0, @EnableWebSecurity, How to validate jwt token in spring boot, spring boot security tutorial
Id: Jen7e6mX6nU
Channel Id: undefined
Length: 112min 12sec (6732 seconds)
Published: Wed Mar 20 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.