Spring Boot 3 + Spring Security 6 - JWT Authentication and Authorisation [NEW] [2023]

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
in this video you're going to learn pretty much  everything you need to know about JWT using Spring Boot 3 and Spring Security  so about three weeks ago we posted a crash  course on Spring Security 6 and there was a lag with   JWT section so we decided to re-record the entire  section and actually make it so extensive this   crash course right here is brought to you by Alibou  and is the one that led the spring security so   go ahead and subscribe to this Channel show some  love because it's going to be bringing you awesome   content like this from time to time security  is a must when designing and building apis and   it's really important that you understand Spring Security and JWT so  that you can secure your apis before we crack on   literally just take one second and smash the like  button also if you're new to the channel subscribe   and if you haven't joined the private Facebook  group as well as Discord go ahead and join because   the community is growing going and we're waiting  for you so without further Ado let's kick off I just want to say that you can grab the entire  source code and the description of this video so   that if you have any issues or you want to  take what you learned from this course and   then apply it within your own API you can do  so feel free to clone the repo and yeah just   just use the code as you intend and if you  have questions regarding JWT literally just   ask on the community and someone within  the community will be able to help you before we start the implementation process let  me first explain to you how this JWT validation   mechanism works the whole story starts when a  customer and a client send an HTTP request to our   backend system which is running using spring boot  container run running on an Apache Tomcat embedded   server so just a reminder for you the first thing  that gets executed within a spring application is   the filter so anytime and each time you create  a filter just notice and remember that it will   be the first thing that gets executed within  our application so in this case the first thing   that will be executed is our JWT authentication  filter and this is only a once per request filter   and has the role to validate and check everything  regarding the token or the JWT token that we have   so now let's start the process the first thing  that will happen we will have here an internal   check to check if we have the JWT token or not  so if the token is missing as we can see here   we will send a 403 response to the client so  and the reason is this missing JWT all right so   now we have our GWT token and then after that we  will start the process or the validation process   so this validation process will start in this  way so the filter like the internal execution   will first make a call using the user details  service to try to fetch the user information   from the database and this we will base on  the user email that we will set as a claim   or a token subject that we will extract within  this JWT authentication filter so I repeat again   this JWT authentication field will check the  JWT token extract the username or the email or   we call it the subject when we talk about JWT  tokens and it will use that email to fetch the   user details information from our database okay  so this is the first call then once the user   is fetched we have the response from our database  and the response can be either way can we existing   user or non-existing user okay so once we get the  response to our JWT authentication filter here we   will make a few checks which is if the user does  not exist we will also send a 403 to our customer   in case everything is fine and we get our user  from the database we will start then a validation   process so this validation process because the  this JWT token was generated for a specific user   so we want to validate this token based on the  user and here we have this validate JWT process   or mechanism which will try to call a JWT service  and this JWT service will take as parameter   uh the the user itself and also the token or the  string token or the JWT token call it whatever   you want after the execution of this validation  process here we have two case scenario so the   first one the token is not valid so it's not so  for example the token is expired or the token is   not for that specific user so what we do we will  send also a 403 back to our customer so and the   reason will be this and valid JWT token otherwise  what will happen we will call or we will update   the security context holder and set this connected  user because when we fetch the user details   information from the database we will be able to  set this security context holder so we will tell   spring or we will tell the set of the rest of our  filter chain that this user is now authenticated   and we will update the authentication manager so  every time we check if this user is authenticated   for this request the answer will be yes once the  security context Holder will be updated it will   automatically dispatch the the request and it  will be sent to the dispatcher servlet and from   the dispatcher servlet it will be sent directly to  the controller we will do all the execution that   we need to do for example calling the service  going to the database and so on so forth and   then we will send back the response for example it  can be a JWT and it will be a HTTP 200 or whatever   any process that will get executed within this  controller so this is how JWT authentication   mechanism works now let me show you how to  implement this and how to realize these steps let's first start by creating a new spring  boot project to do so the recommended way and   the weight I also recommend is going is going to  start.spring.eu which is the spring initializer   and create a new project from that so first of  all make sure you will use Maven this is what   I will be using in this video and tutorial then  we want to use the recent version of spring boot   which is now 301 okay and also here make sure  you select Java 17 because the minimum required   version which is compatible with spring 3 is Java  17. next select the jar packaging and now let's   fill this project metadata so for the group  ID I will call it com.alible and the artifact   I will call it security okay so I will leave  the rest as it is and now I will move on and   add some dependencies so first of all we need  the spring web because we want to expose few   endpoints we need also the security and this is  the main object of this video and then we will   need GPA or spring data jpa because we need  to manipulate and interact with the database   then we need a post degree SQL driver to connect  to post degree SQL you can also use any other SQL   database like MySQL or Oracle or whatever finally  we want to use lombok to reduce the boilerplate   code so now we have our project ready we can just  go ahead click on generate and start decoding as I mentioned before we will be using post degree  SQL or as a database for this application so let's   first start by configuring our data source for  that I will be using ntdj and I will use this   database tool so this one is available only with  the ultimate version otherwise if you don't have   the ultimate version just make sure you install  post degree SQL and you can use the PG admin or   you can use the dbiver tool to connect to any  data source okay so let's start with that click   on here and then we have this class icon so  click on this plus icon and then we want a   data source and then filter for post degree SQL  click on that and to be able to connect so make   sure here if this is the first time you will have  instead of driver post degree SQL you will have a   link or you will have a button here to download  the driver so just go ahead and click on it and   download the driver next the host is localhost  because it's the local one and the default   port for post degree SQL SQL is 5432 then if  you create when you created your post degree   SQL did you made or did you choose a username and  password if yes so just go ahead and specify them   here so for me for the purpose of this tutorial  I made it Amigos code and for the password it's   just password okay and then once you fill all  this information just to check if everything   is working fine click on this test connection  and make sure you get this succeeded otherwise   just check your configuration all right so now  everything is done I will go ahead and click on OK and the first thing that I will do is  I will create a new database so right   click on this data source new and then database so I will call it JWT security and then hit OK so the first time it will not be  automatically shown so just click here on this   2 of 8 the number the numbers May might change  from one laptop to another and here I want this   JWT security okay so open it in here and here we  can see that we have zero of three schemas just   select the public one because this is the one we  need and this is where we will find all our tables   once we create them so now we have our data source  available let's move on to the next step foreign now let's establish a connection between our  application and the database we just created   so the first thing to do is go here to this  application properties and rename it and use the   representation yaml okay so this is what I prefer  personally and you can keep properties if you want   to but to better follow this tutorial it's better  to transform it to yaml so in order to connect   to a database we need to provide a bunch of  properties right here so we will start with spring   and then data source and one of the of  the things that we need to provide at   first is the URL and this one is a URL of the  connection string to our database if you don't   know it just go here to this database click  on it right click on the the connection you   just created properties and you copy this one  you copy this part right here it's gdbc colon   post degree SQL and then the address Port  slash the database so let me close this I will just paste this one and make sure  here you you write the correct database   name so for us we call the JWT security now  we need to provide the username and password   okay so for my case it's empty make sure you  provide the correct one and here it's password so next property is after providing the  data source information we want now to   give some other GPA properties okay so  here it will be jpa and then hibernate   and here I want to tell spring what  to do at the at the startup or update   application startup and this property is  the ddl auto and here we have a bunch of   options so we have create drop create non-update  the end validate so I will be using the first one   because every time I want to start the application  I want to create a new database a new schema and   when I stop the application I want to destroy it  okay so I always want to start with empty database   all right so the next one within JP within jpa  like you see now you need to really pay attention   about the indentation right here because this one  the CTL Auto is part of the hibernate and the one   I will write right now is part of jpa so it's  spring jpa and then show SQL I want to show SQL   when when we perform or when spring data jpa  performs um a query I want to see that gray okay   I want also to add some other properties so here I   will type properties and one of these  properties and here I have hibernate and within this hibernate I  want also to format the SQL   so format SQL and true I want my queries to  be formatted now go back to the same level   as properties and provide some information  about the database so here we want to tell   jpa which database we are using and for this case  we are using post degree SQL and then we can also   provide the database platform that we are using  and this will help spring performing and writing   the better queries to to suit our post degree SQL  database so for this one it's org dot hibernate dot dialect dot postgre SQL dialect   all right and here we just forgot one property  right here which is the driver class name so   this will help a spring to detect or use the  best driver class name and here we are using   post degree SQL so and 3dj will automatically  propose it to you otherwise it's the org.post   degree sql.driver and this is the one that we  got from the post degree SQL driver dependency   all right so that's it about this configuration  let's move on and start implementing our security when we talk about authorization and  authentication we mainly talk about   users so let's go ahead and create our user class  so within the Java package and within the main   package that we have right here right click and  new class and here we can create a package and   a class at the same time so the package I will  call it user and here I will just call the class   user so user.user will create a packet user and  inside of it it will create a class user all right   so this is our user class let me make this one  full screen and now I want to write a bunch of   properties within this class okay so my user has  the the following characteristics or the following   Fields so first of all I want to have an integer  ID and then I want to have a string first name and private string last name   and also of course we need an email and password  for this user to be able to authenticate and   connect to our application so here I will  add email and also private string password so these are the information about our user now I  will add a bunch of loanbook annotations in order   to reduce the boilerplate because you know  when we create a class we need Getters and   Setters we need Constructors we need also the  design pattern Builder to build to be able to   easily build our object and so and so forth so  let's start with that so we will need the date   annotation and this annotation will provide us  with is the equivalent of getter Setter as you can   see here so it generates Getters for all fields  for useful method methods to string and so on so   forth so it's the equivalent to the getter Setter  required as Constructor to string and equals and   hash code okay also I want to use the Builder  annotation so this Builder annotation will help me   build my object in an easy way using the  design pattern Builder okay and also I   will need the no arcs Constructor and of  course when we talk about design pattern   Builder we need always the all construct the  or arcs Constructor okay so let's add this   one and like this we have our we have our user  class now let's make this user class an entity to make this user class an entity so the first  thing we need to add is this entity annotation and   since we are using the Springwood 3.0 here make  sure that the package is jakarta.persistence and   it's no longer Java x dot persistence so this also  will help you tell if you are using the correct   version of springboot okay so here we need the  entity annotation and because this username this   user class is already reserved for post degree SQL  because post degree SQL already has a table called   user so we cannot create a second table called  user I will use the table annotation right here   because you know the table annotation if I do not  provide if I don't provide any name right here it   will take the entity or the class name him as a  default name for the table okay but here I want   just to call it underscore user to avoid this  ambiguity between this user class and the one   with and the one with post degree SQL so now this  is kind of sufficient to tell that this user class   now is an entity but we still need to provide one  small information okay so here we have this error   right here we see that this persistence entity  user should have a primary key okay so we need   to add and add an ID attribute which we already  have right here but we're still missing this ID   annotation so this ID annotation it's coming  from the jakarta.persistence and it's telling   that this ID is the unique identifier of this  user class now I want also this ID to be Auto   incremented or Auto generated so every time I want  to create user I don't need to provide this ID and   every time this ID is null I want it to be Auto  incremented by the system or by Spring data jpa   so to do so and to make it in an easy way  I will use The annotation generated value   okay so this generated value it will make this  ID or this object Auto generated using whether   a sequence a table and so on so forth and we  call this strategy so for this strategy we have   we have several options okay we have Auto identity  sequence table and uui ID so the auto is the   default value identity means that it would use an  identity number like an auto increment sequence   means that we will create a sequence within our  database and use this sequence to increment each   time the value of the ID the table this means  that we will create a table and the database and   we will call it by default it's called hibernate  sequence and this table will always be requested   and queried by a spring data jpa to get the last  value and increment it for the last one the uuid   is using this one I think you know it from from  the Java Java utils but if you leave it to Auto if   you leave the generation type to O2 hibernate will  try to detect the best suitable option for you for   example if we are using post degree SQL it will  pick by default sequence if you are using MySQL   for example it will pick table because my SQL  does not work with sequences so it will it will   pick table for that so for the moment I will just  keep it empty like this because as I mentioned the   default value is auto so it will be automatically  detected okay so now we have our entity let's try   to start the application and make sure that  we have our table created within the database here enable The annotation processing for lombok  and now we have our application started let's   have a look quickly on the logs and here we  see that create sequence user sequence start   with one increment by 50. this is automatically  generated as I mentioned and here we see the   SQL that we have create table user with an ID  email and so on so forth okay and here we have   Spring Security is auto generating a security  password and this one we will see later on okay   so also if you want to check you can open your  database right here click on this one refresh it   and within the public schema we see that we have  this user table right here and if we open it   we will see the ID or the attributes  attributes that we already provided when Spring Security starts and set up the  application it will use an object called user   details and this user details is an interface  that contains a bunch of methods okay and each   time you want to work with Spring Security you  need to ensure that you are providing this user   details object in order to make a Spring Security  life easy to use okay so to do this for us for   our user I recommend this way so every time  you have a user think always to make it or to   implement user details interface so like that  your user or your application user is already   a spring user if we may say so okay so to do  that just go ahead to the to this user class   that we created and Implement an interface called  user details okay and this user details is from   the package.org.spring framework security core  user details okay click here and now it will   ask us to implement a bench of method so click  on this one Implement method and we see right   here that these are the methods that we want  or that we need to Auto generate okay not Auto   generate but we need to implement so it's get  authorities username and we have this Boolean   methods account expired logged and so and so  forth okay so just go ahead click OK and we will   see how to override but before that I want to go  a bit a bit uh more into details about this user   details interface so I will open the definition  download the source so we can easily see it   so here if I click on this icon right here to  see all the implementation of this interface we   have this mutable user mutable user details and  so and so forth and also we have our user class   the one that we created and we can see also  that we have this user from Spring framework   security core user details and let's have a look  on this one okay so this user detail contains the   username password authorities and the bunch of  booleans the account expired locked non-expired   and enabled or not and this information or these  uh this attribute spring will use automatically to play with authorization and authentication  and for example if we can rely on this account   non-expired but if we want to have some expiring  dates or use the user can expire and also if we   want to lock and unlock the user or the same if we  want to work with credentials and so and so forth   okay so I will I will give you the the time to  play and check this and here we see that we have   a bunch of Constructor and we have these methods  that they need to be overridden right here okay so   here we see that this user already implements user  details so for you you have two options whether   you implement this user details interface within  your user class or you can create for example a   user you call it app user and then extend the user  the one from Spring boot so it will be the same   but for me I want always to have control over my  object so I create my own user class and Implement   user details so now let's go ahead and implement  this methods okay so here the first one is we need   to provide a collection of granted authorities and  already the method is called get authorities so   these get authorities will return or should return  a list of roles like let me explain it like that   when we talk about roles so here we need to add  a role okay so I will do or I will create a role   and this one it will I will create  any num for it and I will call it role   and this let's create this class and here you can  choose the option create a num role hit OK and we   want to create it within the same package and  within this rule it's so easy I will just user   and admin okay so we we want to have only two  roles within our application so now we have   this Rule and because it's an enum we need to add  this enumerated annotation and this enumerated   annotation is to tell spring that this is an  inam and we want to use it whether the in-am type   uh ordinal or string so by the way by by default  it's original means it's a zero one two and so   on so forth string it will take the string value  of of the of the inner okay so let's go back to   this get authorities so in here because um with  our design we said or we decided that user can   have only one role so I will just return a list  dot off and here I want to return a new simple   granted Authority okay so the object that I want  to return is called Simple granted Authority and   here I want to return the role dot dot name okay  so the role is referencing this role right here   next one is this get user name so the username  for us is our username so it's the email okay   then we have this account not expired so here  we have this is account non-expired here make   sure and be careful it's non-expired false this  is the negation so non-expired should be true   otherwise we will not be able to connect  our users so non-expired not locked and   non-credentialed on expired and if the user is  enabled false and here I want to make it true   here there is one thing that I need to mention  right here so within this method let's go back   to this user details interface we see that  we have this get password okay but this get   password was not uh was not overridden right here  because we have this string password right here   and we have The lombok annotation so we have  already the method called get password but here   if I just name this one we see that we will see  that here we will automatically tell that we want   to override this method okay so let's override  it just to be to be more visible or like better   visible for you I will rename this one to password  and here for this password I will just return my   my password okay so I just wanted to mention this  one so in the next time or like when you have a   different name for this password field you don't  get surprised when you see this get password or   when you have this password exactly like that and  you don't see it so now you know the reason why   okay so now we have everything we need  within our user details so we created   a new role and we overridden or we defined all  the methods that are required by Spring Security now our user is ready so let's move on and create  a repository for that user class so the repository   is the class which is responsible to communicate  with the database so when working with spring data   GPA we don't need to create a class all we need to  do is create an interface and let's call it user   Repository and this user repository to make it a  repository all we need to do is to extend another   interface called jpa repository okay and as you  can see here this jpa repository is from Spring   framework data jpa and so on so forth and it's  a generic interface that takes a t so which is   the class and an ID which should be the ID of our  user class so let's use this one and pass these   types so this the user and we used integer  as an ID so let's pass integral right here   okay so now our repository is ready and as you  know the spring data jpa has also a bunch of   methods or ready to use methods like save find  all find by ID and so on and so forth okay now   I will create one method that we will need later  on and this method will will try to retrieve or   find a user by email because email is unique so  we need to find or we need to fetch a user by   its email all right so I'm gonna create this  optional user and like optional is a generic   type so it's an optional off user and here I  will use the query method provided by Spring   and I will use the method find by and here  all you need to do is providing the attribute   or the field name that you have within your  class so for our case it's email for example   if you use username just find by username and  here all I need to do is to pass string email   all right so this is it now we have our repository  ready to use let's move on to the next steps when we when we check again our schema right here and  the architecture that we have right here so we   see that the first thing that we will get or  the first thing that will intercept our HTTP   request is the JWT authentication filter  so let's go ahead and create this filter so here within our base package  right click right here new   and I will create a new package I will  call it config so I want all this to be   part of my configuration package and I  will create a JWT authentication filter   I will call it like that so this is our  authentication filter class and now in order   to make it a filter we have multiple options okay  but here as we can see in this schema right here   we have the we want this filter to be active every  time we get a request so every time the user sends   a request we want our filter to get fired and do  all the job that we want that we wanted to do okay   so this one we need to extend a class called once  per request filter and as the name indicates it's   it will be a filter by one every request so let  me download the data source and you can see here   once per request filter extends already generic  filter bin and this generic filter being already   implements the interface called filter so for us  we had two options whether using or extending this   once per request filter or implementing the filter  interface right here so it will be the same but   let's use something already provided by spring so  it's better to use the ones per request filter so   now let's implement the methods and we see  here that we have a method called do and   filter internal and we have three parameters to  request the response and the filter chain let me   explain each part of it I will just align these  parameters right here so you can see all of it so these are our parameters so here we what  we have we have this HTTP servlet requests the   response and the filter chain so the request  is our request and the response is also our   response so we can intercept every request  and make and extract data from for example   from the request and provide new data within  the response so for example if I want to add a   header to my response we can do it using this  once per request filter okay and the filter   chain is the chain of responsibility design  pattern so it will it contains the list of   the other filters that we need we need to execute  so when we call this filter chain dot do internal   filter or do filter it will call the next filter  within the chain so here I want just remove this   uh These Warnings so because this uh these  three parameters they should not be null   and to do so I will just add this non-null  annotation the one from springframework.lank   and I'm gonna copy paste it and move it and  put it in here okay so like this we no longer   have this warning and now the last thing to do  before moving on and start implementing this   the last thing to do is we need to tell spring  that we want this class to be managed bin okay   or to become a spring pin and to do so we need  to annotate whether with service annotation or   component annotation or also repository it  works because three of them are the same   annotation the repository and the service  they both extend the component but I will   just make it a component right here and also I  will use another long book annotation which is   the required RX Constructor and this required  arcs Constructor it will create a Constructor   using any final field that we declare right here  so for example if I use if I do private final   string my string this annotation it will create a  Constructor using this private final field Okay so   now we have our filter ready to use let's  now start implementing it part by part from this diagram right here we see that  the first thing that gets executed or the   first thing we do within this JWT  authentication filter is checking   if we have the JWT token okay so  let's move on and implement this all right to do so within our method do  internal filter let's try to perform some   operations okay so first of all I will create a  string I will call it authentication header all   right why because when we make a call we need  to pass the JWT authentication token within   the header so it should be within a header called  authorization so what we need to do here is create   is try to extract this header okay so this  authentication header is part of our request   and from the request we can call a method called  get header and within the header we can all we   need to do is to pass the header name so our  header is called authorization like that so this   is the header that contains the JWT token or the  bearer token we call it also computer token okay   all right so now I will create another variable  let's also make it final string I will call it JWT   or JWT token call it whatever you want so here I  want to implement this check that we did before so   we we talk about here we talk about this check  JWT token so let's go let's implement this so   here the test that I want to do is if the author  authorization header is null so I want to do an   early return or if not my authorization header dot  starts with because as I told you the build token   should be always or should start always with the  keyword beater Okay and it should be exactly like   that and then we have a space so if we don't have  these two conditions all I need to do is call the   filter chain dot do filter and I need to pass  the request and the response to the next filter   okay and here don't forget to call the return  semicolon so we want we don't want to continue   with the execution of the rest of that one okay so  here this is the check that we that we implemented   now let's try to extract the token from this  header okay from this authentication header   the next step is we created already a JWT  variable now I want to extract this token   from my authentication header or from my  authorization header and I want to do a   substring starting from the position number seven  and why position number seven because if we count   this beer with this space the count is seven okay  so let's move on and check what we need to do next after checking the JWT token what we need to do is  to call this user details service to check if we   have the user already within our database or not  okay but to do that we need to call a JWT service   here to extract the username all right so let me  show you what we need to do so right here I will   just go back and create a final string username  or email call it whatever you want so I'm just   gonna call it user email okay to be consistent and  avoid confusions so I will call it user email so   after extracting the JWT token what I need to  do is I want to extract also this user email so this user email equals and here I will add a to-do extract the user email  okay but to do so I need to extract it from let   me add it here from JWT token so to extract  for this user email from the token I need a   class that can manipulate this JWT token okay so  let's try now to implement this class this class   I will call it here I will just create my class  here private final I will call it JWT service   so I don't have yet this JWT service but  within this JWT service what I want to do   here I want to use a method that I will call  it for example JWT dot extract username okay   so let me call this JWT service Dot extract  user name or user email okay let's keep it   username within the JWT because mainly with  Spring Security we talk about user names and   to extract this one I need to pass the JWT as  a parameter okay so um I will create this class   now I will ask antherity to create this class  JWT service and I will create it you can keep it   together with the config with the config package  or you can move it to a different one so I will   keep it within this package and also do not forget  to add this service annotation to make it or to   transform it to a managed beam all right so now  I will just create this extract username method   so create method extract username in JWT service  and yes this is what I want to do I need a method   that will return a string username and  it takes as a parameter string token or   string JWT okay so let me call this one token  I think it would be better as a name and yeah   that's it so I will just return null for the  moment and let's move on and I will show you   how we can how we can implement or how we can  extract this information from our JWT service so now in order to be able to manipulate JWT  tokens generating one extracting information   from the token validating the token and so on so  forth we need to include new dependencies within   our application so let's go open our pom.xml  file and here within this pom.xml scroll down   and go next to the lombok or post degree SQL  dependency and here just add a new dependency   and this is the first one called jjwt API  API and it's from a i o just dot Json web   token okay and the recent version at this  time is the 0 11 5 so let's use this one   we need also to add another dependency  which is also from the same artifact uh   from the same group ID but it's a different  artifact so we need a jjwt implementation   so it's called jjw WT amp and from the same group  ID also the same version you can extract this   version too uh to a property and use it from there  and next we need a final dependency which is the   jjwt Jackson okay so also from the same group ID  and the same version too now once we add or once   you add these dependencies or any dependency  to your palm.xml or if you make any updates to   your pump.xml make sure you click this button  load Maven project but also if you don't see   this button just right click inside the bomb.xml  file Maven and then you have the option reload   project Okay so until DJ will download all the  dependencies and add them to the to the class path   all right so our dependencies are ready to use  now we will go back and implement this JWT service so before we go and Implement all the services  and dive too much into the code let's first try   to understand what is a JWT token so a JWT token  stands for a Json web token which is a compact   URL save means of representation of representing  claims to be transferred between two parties the   claims in JWT are encoded as Json object that is  digitally signed using a Json web signature okay   so the JWT consists of three parts so here we have  the header we have the payload and also we have   the signature so the header typically consists of  two parts the first one is the type of the token   which is JWT and the sign-in algorithm being used  such as for example hmac or sh-250 256 or RSA okay   the second part of the token is the payload which  contains the claims claims are statements about an   entity T typically the user and additional data  so as we can see here we have the subject we   have the name we have this IIT we have we can have  also extra information like authorities or extra   claims right here okay so there are three types  of claims registered public and private claims the   registered claim claims are a set of predefined  claims which are not mandatory but recommended   to provide a set of useful and repeatable claims  some of the registered claims are is are ISS or   the issuer we also have the subject the the odd  the X exp like the expiration time and so on so   forth this we will see when we will implement the  token Generations okay we have also the public   claims which are the claims that are defined  within the Ia and a Json web token registry or   public by Nature private claims are custom claims  created to share information between parties that   agree using them okay the last one or the third  part of the token is the signature which is   used to verify the center of the JWT is who it is  claims to be and to ensure that the message wasn't   changed along the way okay so now let's move on to  the code and see how we can generate or how we can   extract claims from this JWT token okay so also  within this jwt.ao website you can play with the   payload you can add some information here and as  you can see everything you add some every time   you add something you see that it changes right  here okay let's move on and go back to our code now before start implementing this extract  username method I want to implement or write some   code to extract all the claims and also another  method that allow us to extract one single claim   okay so first of all I want to create this method  I will it will return a claims and this claims if   you if you see right here when you click on import  class it's the one from io.jsonwebtoken.claims   it's the dependency that we just added so this  claims I will call this method extract all claims   okay so this extract all claims of course  it will take a string token as parameter   and now I will show you how  to extract this so to do it   we need to return our jwts and this jwts is also  from so this jwts is also from the io.json web   token and we need this jwts.pars Builder and in  order to pass this Builder or the patopars the   token and here we need to set the signing key okay  set signing key because as we mentioned before   when we try to create to generate or to decode  a token we need to use the signing key so I will   here just let cook call this one get sign in key  and I will explain it later on we will implement   this method and then we need to build because  it's a builder and once the object is built we   can call the method parse claims JW jws okay so  this one this method pass claims jws so we want   to parse our token and once the token is parsed  we can call the method get body okay so within the   get body we can get all the claims that we have  within this this token right here all right so now before we implement this signing key method  which should return a key as you can see in the   definition here so this one let's first understand  what is a signing key okay so in the context of   Json web tokens a signing key is a secret that is  used to digitally sign the JWT the signing key is   used to create the signature part of the JWT which  is used to verify that the sender of the JWT is   who it claims to be and ensure that the message  wasn't changed along the way so we want to ensure   that the same person or the same client that is  sending this JWT key is the one that claims who to   be okay so the signing key is used in conjunction  with the sign-in algorithm specified in the JWT   header to create the signature the specific  sign-in algorithm and key size will depend on   the security requirement of your application and  the level of trust you have in the signing party   okay so here in order to do that first of all  we need to go ahead and generate a new token or   a new signing key or a secret secret key okay  so uh to generate this secret key we can do it   online because now we like for security reasons we  need at least or like the minimum assigning key of   size 250 six okay so and in order to generate a  key so you don't need to worry about this there   are so many tools and online tools to to do this  so here I will just go ahead and create a private   static final string I will call it secret key and this secret key equals the value that I will  generate right now okay so now go to the browser   and navigate to this address which is all  keysgenerator.com and then slash random   slash security encryption key generator a DOT  aspx okay and we have here encryption keys and   here we have also the security level so as I  mentioned the minimum required for JWT tokens   is 256 bit okay and then click on this checkbox  yes that the eggs make it check it and make it   yes so we can get this x x secret key okay so  if you need more security just go ahead change   it and do like you can go even up to 4096 bits  okay but for now for the sake of this tutorial   I will just make it or leave it to 256 bits okay  now let's go back to our code and paste this code   right here or this key right here also we can  you can move it to the application properties   and use it from there all right now let's continue  and let's implement this get signing key so here I   will use n3j to Auto generate or to create this  method so I will ask him to create this method   and this method should return not byte but it  should return a key okay so now to do this first   of all I need to create or to make an object or  a variable of type byte I will call it key bytes   and this one equals decoders and the DOT base  64 because it's a base we want to decode it on   base64 dot decode and we want to decode our secret  key okay so once the secret key is decoded now   I need to do just to return keys Dot h m a c  sharp key4 this is one of the algorithms that   we mentioned before and all I need to do is  to pass these key bytes right so now we have   our get signing key method and we have also  this extract all claims method ready to use now we have extract all claims method ready to  use now we'll go ahead next and Implement another   method which will allow me or which can extract  a single claim that we pass okay so I will use   generosity for this so I will use a public T it  I wanted to be a generic method and then we call   it extract claim and for this claim I need of  course the token the key token or string token   and then I want to pass a function the one from  java utils and this function is of type claims   and T which is the type that I want to return  okay I will call it claim resolver or claims   resolver or claim call it whatever you want  resolver and here it's an it's a simple it's   a simple method I will create a final claims  object I will call it claims equals extract   all claims from my token okay so first of all I  want to extract all the claims and then I want to   do return this claim resolver the function  that I pass as parameter dot apply and as   you can see the apply it will take or it will  require a claims T so the claims is the one or   the list of all the claims that we have okay so  this is the extract or claims all claims method   now extracting any claim from my token will be an  easy peasy test so I will show you how to do that so once I have everything ready extracting all the  claims and also extracting one single claim let me   show you how we can extract the username out of  this token okay so extracting a username is easy   peasy so it will be extract claim and we need to  pass the token and only we need to pass the claims   dot get subject okay so because as I mentioned  before the subject is or should be the email or   the username of of my user okay so this should  be the subject of of the token so that's it this   is only uh all about extracting the username  let's now move on and try to implement other   methods that we will need within this JWT service  class like testing if the token is expired also   um extracting the expiration date  generating the token and so on so forth let's now implement the method that will  help us generate a token so the token as   you know is a string so I will create a public  string method and I will call it generate token all right so this generate token  will take as parameter a map a map of string and object okay and this map  of string object will will contain the claims   or the extra claims that we want that we  want to add okay I will call it claims   unlike extra claims I think it's better  to call it extra claims and also I want   to pass my user details so here user details  and it's the one from the spring framework   I will just call it user or user details all right  so this is the method and here this extra claims   is the one if I want for example I don't know to  pass authorities to pass any information that I   want to store within my token all right so to  do this it's easy peasy it's just return jwts dot Builder and then I want to set my claims  so these are my claims and those will be the   extra claims okay so extra claims and after  passing the claims I need to set my subject so the subject as I mentioned before it  should be my username or user email okay   so I will use the object user details dot  get username all right so because for us   username or the unique part of the user is  the email but for spring it's always called   username that's why we are using username  okay so also we need to set the issued ad   means the when this claim was created and  this information will help us to calculate   the expiration date or to check if the token  is still valid or not okay so it I will use a   new date right here and I will pass just  the system dot current milliseconds okay so this is the the issue the issue date  and I want also to set the expiration date   so the expiration date it will be the same a  new date and here like it's up to you to set   how long this token should be valid okay so  also system Dot get dot current milliseconds and then for example I want to add let's say 1000 times 60 which is 60 Minutes times 24 so my  token for example will be will be valid for   24 hours plus 1 000 milliseconds okay and then you  can you can decide or you can set any expiration   date that suits you okay the final step is to sign  with like which key that we want to use to sign   this token and the signing key is the get signing  key method that we already created before and then   we need to pass also the signature algorithm  so signature algorithm and then we want to use   the eight the hs256 okay so it's this one so let's  select it and then finally call the method compact   compact is the one that will generate and return  the token so as you can see this is how we can   generate a token out of extra claims and the  user details all right so now this method will   um like we don't have a choice but passing claims  and user details but what if I want to pass or I   want to use um or I want to generate a token  without having or without extra claims I only   I only want to generate a token from the user  details itself so it's easy peasy I will create another one public string I will give it the same name  generate token and the generate token it   will take it I will pass only user details as a  parameter and here I will just return generate   token out of null or let's say a new hash  map like an empty one and then user dictates okay so now I have this generate token  method that I can use later on okay as a Next Step let's Implement a method that  will validate or can validate a token Okay so   I will create a Boolean and I will call  it is token valid all right and this   token this method is token valid will take two  parameters as input which is the token itself   and the user details why we need the user details  because we want to validate if this token right   here belongs to this user details right here okay  so first of all I need a final string username or   user image but within this within the context of  this JWT service let's stick to username and this   one it would be extract username out of the token  we already have the method for that and then then   what we want to do is to return if or whether  the username that we have right here equals   the user details Dot get username all right so we  want to make sure that username we have within the   token is the same as the username we have as input  okay and I want to make sure is is token expired   like I need to check that my token is not  expired okay and I want to pass my token   as parameter so this is token expired this  is a method that we need to create so let me   go ahead and create this token expired  and let's implement this token Okay so   I want for this is token expired I want I will  create a method I will call it extract expiration from the token that we have dot before because we  it's a date so it I want to make sure that it's   before today's date okay before new date  now let's create this extract expiration so this extract expiration should return a  date and it has or it passes as a parameter   the token itself so it's also easy  so it's extract claim from the token   and then it's claims dot dot or Colin colon get  expiration okay so this is how we can extract   the expiration date all right so how we have  here if uh the East token expired we have the   is token valid we have all the methods that we  need so is still converted this one will use it   later on so now let's move on and go back finish  implementing this authentication filter foreign so here we just finished implementing this JWT  validation process or validation service right   here and now we want to go back to this validate  JWT process so within our code what we did here   we extracted our user name so we have now our  username valid let's go ahead and perform or   finish our validation process all right so here  I want to check if my user email is not null   so I have user email or I can extract my user  email out of my JWT token and I want to check   something else I want to check that the user  is not authenticated yet because if the user   is authenticated I don't need to perform again  all the checks and setting or and updating the   security context and so on so forth so here I want  to check if the user is already authenticated I   don't need to do all this process and so on so  forth all I need to do is pass here and leave   it to the dispatcher servlet okay so to do that  or to check if the user is already connected or   is already authenticated or not we have  an object called security context holder and from that we can get the context and then  we have a method called get authentication and   when the authentication is null means that the  user is not yet authenticated okay so this means   that the user is not connected yet all right  so once the user is not connected what we need   to do here like when we go back to follow this  process we need to perform and to check or get   the user from the database all right so once  we do this validation process we want also or   we need to check if we have the user within the  database all right so to do so I will create an   object called user details or we you can just  call it user because our user already extends   or implements the user details interface I will  call it user details equals and here I will use   this dot user details service which we don't  have yet and here we have a method load by user   username okay and you and my username  in this case is the user email all right so here the method called load user by username   and in this case we don't have this user  detailed service but let's create one here so this user details service is already  an interface within the spring available   within the spring framework and it's from  Spring framework security core and so on so   forth and I will call it user details service  so this interface if we check it right here so here we have some implementation for it okay  but we want our own implementation because we   want to fetch our user from our database  all right so make this one final don't   forget this and let's move on and implement  or provide a bean of type user details service at this level we need to create a bean of type  user details service or we need to create a class   that implements this interface so and also give it  the service or component annotation so it becomes   a managed bean and spring will be able to inject  it but let's do it in a fancy way within this   config package I will create a class I will call  it application config so this application config   will hold all the application configurations such  as bins and so on so forth all right so to make   this class A configuration we need to annotate  it with The annotation called configuration so   at the startup spring will pick up this class and  try to implement and inject all the bins that we   will declare within this application config all  right we also need the required ice Constructor   in case we want to inject something so what we  need to do now is to implement or to create a bin   of type user details service and to do so first  of all we need to use The annotation bin this to   indicate to Spring that this method represents bin  and a bin always should be public no private means   and our bin is of type user details service okay  so let's call it user details Service as easy as   that or as simple as that and then we can use  a Lambda expression so we can use or we can say   return a new user details service and we implement  the load user by username so we can do like that   new user details service like this and  automatically you will see here that we   have this load user by username method  the one that we want to use in here this method right here okay but but we can make  it more simple than that and we can use a Lambda   expression and the Lambda expression it's it looks  like that so here we all we already see that uh   anteriority is proposing to replace this with  a Lambda so we'll just go ahead and click on it   so the Lambda is the username so we provide the  username the one we have as an input within this   method right here and then we need to provide  the implementation Okay so in this case what   we want to do is to fetch the user or to to get  the user from the database and to do that we need   to inject our user repository okay so let's  create a private final user Repository let's   call it repository or user Repository and here  simply what we need to return is user Repository dot find by email the method that we created when  we just created the user repository and find by   email we need to pass the user name okay and since  defined by email returns an optional off user here   I want to add an or else throw so in case we  don't have or we don't find the the username   or the user within our database we need to return  an exception of type where the entity not found   exception or we can also return the exception  username not found exception okay so I will use   the username not found exception and I will just  provide here it should be also Lambda and for   example as a message we can say user not found  all right so here now we have our user details   service so now it's ready to use let's continue  implementing our JWT authentication filter now we can go back to our filter and finish the  implementation all right so here we have our user   details or we have our user and the next step is  to validate and check if the token is still valid   or not so here I will add the if JWT service dot  is token valid okay and here I need to pass my   JWT and the user details that I just got from  the database all right so if the token is valid   then what I need to do I need like we have in here  we need if the user is valid we need to update   the security context and send the request to our  dispatcher servlet okay all right so once the our   token is valid I need to create an object of type  username password authentication token so username   password authentication token I will call it auth  token and this object is needed by by Spring and   by the security context holder in order to update  our security context okay so equals new username   and password authentication token and it takes as  parameter the user details and then for the next   parameter for the authorities I want to pass it  as null and then the user details.get authorities so here because we are we don't have credentials  as you remember when we created the user we   don't have credentials so that's why I'm  passing these credentials as a null value   so once I finish creating or finish instantiating  this user name authentication token I want also   to give it some more details so I will use the  auth token dot set details and this details it   takes an object so I will pass a new object  of type new web authentication detail source authentication details source   and here I want to build the details out  of our requests out of our HTTP request all right now the final step is as we  mentioned here the final step is to update   the security context holder so to update the  security context holder it's security context holder dot get context dot set authentication  with our authentication token all right and   that's it now like let's recap this one so here  when if we have our user email and the user is   not authenticated we get the user details from the  database and then what we need to do we check if   the user is valid or not if the user and the token  is valid so we create an object of type username   password authentication token we pass user details  credentials and authorities as parameter and then   we extend or reinforce this authentication token  with the details of our request and then we update   the authentication token and don't forget as  a last step and always do think about after   this if think about always calling our filter  chain dot do filter so we need always to pass   the hand to the next filters to be executed okay  and here we need the request and the response   and that's it about our JWT authentication filter   it is ready to use let's move on and  see what we need to implement next this whole process is now implemented  but we still need to do some extra steps   the extra step we need to do is to tell spring  which configuration that we want to use in order   to make all this works okay so we created the  filter we implemented the user Detail Service   validation updating context and so and so forth  but what we are missing is The Binding we need to   bind because we created a filter but this filter  is not yet used so we need to use it and in order   to do that we need to create a new configuration  class I would call it security configuration   okay so I will call this class  security config or configuration   and this is going to be our security configuration  class and as always to make a configuration class   become a configuration we need to add this  configuration annotation from Spring also   because we talk about security right here we  need to enable web security let me make it full   screen and again we will need the required arcs  Constructor so these two annotations they need   to do they need to be together when we when we  work with springboot 3.0 okay so next whatever   what I will need to do because as at the startup  or at the application startup Spring Security will   try to look for for being of type security  filter chain and this security filter chain   is the bin responsible of configuring all the HTTP  security of our application so I will create a bin   public security filter chain I will call it security filter chain and  within this method of this bin I will pass   a parameter of type HTTP security I will call  it just HTTP just for a short variable name now let's start configuring our HTTP security  so here as you can see it's type it's of type   security filter chain and to do that let's first  return HTTP dot build and here we need to add   also the exception to the method signature  because this build might throw an exception   all right so now to do the configuration I will  start by HTTP dot I will first disable the csrf   um verification and we may we made we might talk  about this in in a different in a different video   so here now once we disable this one and  now let's move on or we will implement   the configuration the real configuration  So within the security we can choose and   decide what are the URLs and the pathways  that we want to secure but of course Within   every application we have always a white list  whitelist means that we have some endpoints   that they do not require any authentication  or any tokens but which are open for example when we talk about creating an account and logging  so in this case to create an account we don't need   a JWT token because at that time we will create  a user account and we will require or will ask   for a token after that also the same when we  want to log in we don't need to pass the token   as parameter because we don't have one yet so in  this case this is when we talk about whitelisting   and here is how we can Implement white listing  so after disabling the csrf I want to authorize   HTTP requests and after authorizing after using  or calling this authorized SCP request here we   can call a request matcher Dot request matchers  and for this request matches we can pass a list   of strings and a list of patterns this will  represent the application or our application   patterns we will go back to this later on and  for this list I want to permit all I want all   the requests in here all the all this list I  want to permit all okay and then any request   all the other requests I want them to  be authenticated so this means I want   to whitelist this this list and authorize all the  requests within this list but any other request   should be authenticated okay now let's talk about  and let's see how we can configure our session   management decision management means what we said  that when we implemented the filter we want a once   per request filter means every request should be  authenticated this means that we should not store   the authentication State or the session State  should not be stored so the this the session   should be stateless and this will help us ensure  that each request should be authenticated okay   so now we use the end to add a new  configuration and here let's add Dot session management and here I want to talk about  the session creation policy how we want to create   our session so as I mentioned our session we want  it to be stateless session okay so I will use   session creation policy dot stateless and like  this spring we'll create a new session for its   request and then and here I need to tell spring  which authentication provider that I want to   use the authentication provider I will explain it  in just a few seconds okay so I will just add it authentication provider and I will create  an object of type authentication provider and then I will go back and create it later on and  then after the authentication provider I want now   to use the JWT filter that we just created okay so  to do that I will use the method add filter before   because I want to execute this filter before the  filter called username password authentication   filter because as you remember when we implemented  the JWT authentication filter we check everything   and then we set the security context we  update the security context holder and after   that we will be calling the username password  authentication filter okay so here I will use   JWT auth filter I will call it like  that and I want it before the user name   password authentication filter.class okay now let's let me create this object so  I will use the oops not local variable   but create a field and this one I want it  to be of type JWT authentication filter   okay so this is the first  one and I need it to be final   so it will be automatically injected by spraying  and the next one is the authentication provider so let's create a field of type authentication  provider and let's make it final too   all right so now I have my configuration  ready all I need to do or I need to   implement now is this authentication  provider and let's do it right now now we need to provide this authentication  provider bin so let's go to our application   config class and let's create a  new bin of type authentication   provider okay so for this authentication  provider let me make this full screen so I want to create a bin foreign type Authentication provider oh authentication  provider always from the spring framework package   and I will call it authentication provider  and let's start implementing this bin right   now so this authentication provider is the data  access object which is responsible to fetch the   user details and also encode password and  so and so forth so for this we have for   this authentication provider we have many  implementations and one of them is the Dao   authentication provider so data access object  authentication provider I will call it auth   provider equals new Dao authentication provider  okay So within this authentication provider we   need to to specify few Properties or like not  few but just two of them and the first one   is the user details service so we need to tell  this authentication provider which user details   service to use in order to fetch information  about our user because we might have multiple   implementations of the user details one for  example getting the information from the database   another one based on another on a different  profile fetching the users from from in-memory   database from ldap and so and so forth okay so for  this one we already have our oops we already have   our user details service right here so this one is  referencing this method next we need to provide a   password on encoder so which password encoder we  are using within our application so if you have   a specific one or if you are using specific one  you need also to precise this one because when we   want to try or we want to authenticate a user we  need to know which password encoded in order to   be able to decode the password using the correct  algorithm okay so auth provider Dot set password   encoder and here I will create a method I will  call it password encoder okay and I will create   a bin out of it later on so this is the minimum  required information that we need to provide and then all I need to do is returning this auth   provider right here now I will just go  ahead and create this password encoder so this password encoder is also should be also  a bin so it will be public and I will give it   the bin annotation and for this I just need to return a new  decrypt password encoder and that's it so   now I have my authentication provider and  also I created the password encoder bin one more step is needed to finish this application  config class which is the authentication manager   and the authentication manager as the name  indicates is the one responsible to manage   the authentication so the authentication  manager have or has a bunch of methods and   one of them there is a method that allow  us or help us to authenticate user based   or using just the username and password and  for that we need also to create a bin or to   provide the bin to be able to use it later  on okay so I will create a bin and public authentication manager because this is  the being that I want to to create and   I will call it authentication manager and within   this mean I want to inject an object  of type authentication configuration   okay and I will call it config this authentication  configuration hold already the information about   the authentication manager so I will just return  config dot get authentication manager all right   so here we are using the default implementation of  springboot and this is more than sufficient for us   here don't forget also to add the exception to the  method signature so that's it let's move on and now we're done with all the security  configuration for our application but we   still need to provide at least two endpoints  where the user can create an account or also   can authenticate and to do so within the  base package I will create a package I   will call it auth and within this package I  will create a new controller Authentication   controller and this authentication controller will  have two endpoints that will allow me to create   or register a new account and authenticate an  existing user so in order to call this or to make   this class a controller we need this annotation  rest controller and also I will give it a request   mapping and for the request mapping it will be  slash API slash V1 slash auth and also I will need   the required arcs Constructor okay now within  this authentication controller I will create   two endpoints one for resistor and the other one  for the authenticate so the first one it will be   a post mapping and I will give it a register for  the name and here it will be a public response entity and now the type will be authentication  response I will create an object later on   for that we will call this method register  and this register will need a request body   and this request body I will create an object  called register request which will hold   all the requests or the registration information  like first name last name email and password okay   so I will leave it empty for now  we will implement it later on   I will do the same I will just copy paste  this one and I will create another method   but this one we call it authenticate and it  will also return an authentication response   but instead of register request we will  need an authentication request okay so it's an authentication request   yeah that's it so we have our controller ready  now let's move on and start implementing things let's now create our authentication response so  now just I mean I will use ntvj to create this   class authentication response and I will  click create it within the same package so this response is a simple  class that will have only a string   token so this is the token that would be  sent back to the to the customer or to the   user and to do that we will need this  data annotation we'll need the Builder   and of course the all arcs Constructor and  the no arcs constant so that's it so our   authentication response is ready let's  move on and create the register request now let's create this register request  class so create a class right here and   we will create it within the same package   so this register request it will also have  few attributes like private string first name private string last name and also an email and password so we will also need the same annotations as we  used within this authentication response so just   go ahead and copy them and put them within this  register request okay so now we have also our   object register request ready I will create as  a Next Step the authentication request object finally we need to create this authentication  request within the same package so I will just   paste the same annotations and here this  object will hold only two information which   is the string email and string password  okay so that's it our object now ready   let's move on and start implementing this  author register and authenticate request so for the registration and authentication  implementation I will delegate this to a service   so within this auth package I will create a new  class and I will call it authentication Service   all right this is the place or the class  where I will Implement these two methods   register and authenticate so here I will just give   it the service annotation and of  course the required RX Constructor all right so here we have these  two methods I will just move on   and here just make a simple call  for for this service methods but   first let's inject it okay so I will  need the private final Authentication service I will call it just service right here   and within this authentication Service let me  make this full screen now I will just make the   return statements for these two methods all  right so here I will return a response entity dot OK and I will call my service Dot resistor  and I will pass this request as parameter okay   and I will copy paste this and paste it right here  and instead of register it will be authenticate   so here we don't have yet our register and  authenticate method so let's go ahead and   create them so create method register and this  one will return the authentication response so this is what we want to return and now we can also create this authenticate  method and the same it should return an   Authentication response all right so now  I will start implementing these methods so now let's implement this register  method and this register will allow   us to create a user save it to the database  and return the generated token out of it okay   so uh for that because we need or we  want to interact with the database   and see if the user so the first thing  that we need is to inject our Repository let's call it repository right here and  then what we need to do I want to create   a user object out of this register request so I  will create a VAR user equals user dot Builder and here dot build so to build this user out  of this register request so I will have the   first name which is request.get  first name same for the last name and same for email so it's email and then the  value will be the request dot get email now   for the password as you remember we created  our Bean of type password encoder so for this   we need to encode our password before saving it  to the database okay so in order to encode the   password we need first of all to inject our  password encoder service so I will do that password encoder password encoder and this I  will use it right here password encoder dot   encode and here I have the get password or the  request.getpassword that we will receive within   the registration request Okay so here I will  just make a static roll always so I will use   a user role and then we call the build method  all right so once we build our user object the   next step we need to do is our repository dot  save and we want to save the user that we just   created all right and finally to be to return  this authentication response that contains the   token I will create a new variable I will  call it JWT token equals now I will need my   JWT service to generate that token so I will I  will inject also the private final JWT service and I will use it to create or to generate  the token using this user object right here   so JWT service dot generate token the one only  using user details for the moment I don't need   to set any extra claims so I will use this  user object to create auto generated token   and finally I will return an object of type  authentication response dot Builder dot build and I need to pass DOT token or I need to pass the  token that I just generated okay so this is the   register method and now everything is implemented  let's move on and implement this authenticate for the authentication it's it's an easy  peasy so you remember we spoke before about   the authentication manager bin and we said that  this authentic and authentication manager bin   has a method called authenticate which allow us  to authenticate a user based on the username and   password so for that I will inject first of  all my private final authentication manager   bin I will call it authentication manager  all right so I will go back here to this   authenticate method and to authenticate  the user all they need to do is to call   the authentication manager.authenticate and  this authentication manager takes an object   of type username password authentication token so  I will pass a new username password authentication   token and within this I need to pass the email  so request dot get email and also the password   request dot get password and this authentication  manager will do all the job for me and in case   the user is not a username or the password are  not correct so an exception would be thrown   all right so I'm totally secure when I just  call this method otherwise what I need to do   I need to create a user and if the user so  if I first of all if I get to this point   right here means the user is authenticated so  means the username and password are correct   if both of them are correct so I will just need to  generate a token and send it back okay so I will   first of all find try to get the user and find  by email and I will use the request dot get email   and here or else I will just throw okay I'll just  throw any exception like it's not so important at   this level but for you you might want to throw  the correct exception and you need to catch it   handle the exceptions and so on and so forth  all right so now I will just go ahead and copy   this code because it would be the same and put it  right here so once I get the user I will generate   a token using this user object and then return  this authentication response so now we have this   authenticate method and the register method ready  to use let's move on and see what is the next step now we have our authentication controller ready to  use but there is one extra step that we need to do   do you remember when we first implemented  the security configuration and we spoke   about this white list right here  so what we need to provide now   within this request matches that we want to  permit all we need to provide or authorize   all the URLs or all the methods that we have  within this authentication controller so go ahead   copy the request mapping that you created and for  example here I want to authorize all the methods   that I have within this authentication controller  why because based on my design everything that I   have in here only uh authentication related  methods so I don't have any business logic   methods or endpoints within this authentication  controller so that's why I'm allowing I'm allowing   all the methods within this controller so that's  it now let's create a demo controller for that I will create a new controller within a new  package so right click here new class and I   will call the package demo and I will call it  demo controller so this demo controller will be   also secured so I want this endpoint to be secure  they will copy this this annotations right here   paste it here and so this one will be  demo and let's call it demo controller   and now I will create just a  get mapping a simple method that   public that will return a simple string  okay response entity of type string say hello for example and then  I will just return a response   entity.okay and with a body hello from  secured hello from Secret endpoint   and that's it now let's go ahead start  our application and test these changes foreign let's start the application and make  sure that all the code that we wrote together   is working fine so go ahead click on start  and let's see what we will have in the console   so let's make sure that everything is fine  so as you can see here from the logs we no   longer have this auto-generated password by Spring  Security and we have here that we are creating the   sequence and we have the table user gets created  and the application is running correctly okay so   now let's start our Postman and test this endpoint  so I have my Postman started right now so I will   use this end point within a get request so the  endpoint is localhost and my port is 8080 slash   API V1 demo controller is the same one that I have  right here within my code it's demo controller and   now I will click on send we see that we have no  authorization we have nothing in here so I will   just go ahead and click on send and normally  like the expected behavior is this end point   should be secured okay so when I click on send  we exactly can see that we have a 403 Forbidden   means that we are not allowed to access this  endpoint okay next we have our two endpoints   the authenticate and the register so let's first  start with this register endpoint or let's before   that let's start with the authenticate and  for the authenticate now we know that we   have no user within our database we can also  double check that at so if I open let me close   the other tabs so here I don't have any user  registered then within my database okay but   now if I try to connect to or to authenticate a  non-existing user I also expect to have a 403 as   a response and this is what we see right here so  it's 403 Forbidden and the user is not allowed   to access this endpoint and this why because we  have here within our schema so we try to check   and validate everything even if the endpoint uh  even if the end point is secured so we we get into   this authentication filter we validate everything  but once we get to the user details we don't have   the user in the database so in that case we will  send back a 403 to our customer okay so now let's   create a new user so I will register a new user  so I give it alibu as a first name alibu last   name and alibuatme.com and one two three four as  a password so now when I click the send button I   should get generator token or a JWT token as a  response so this is what we see right here so   I will just copy this token and I want to decode  it and let's see what we have within this token   so let's go back to the JWT dot IO website and  paste the generated token in here so we see that   we have the algorithm here which is the hs256 the  one we use to generate this token and we have our   payload so we set already the subject to the  to the user email and we have the issued at   so the creation date and as you can see in here  it was created December 29 and 1414 and this   one will expire at in 24 hours okay so uh this  is our generated token let's go back and test   the authentication right now so we see that the  register is working but let's ensure that within   this same username and password we are also able  to get a token or to generate a token so this is   the same email and the password that we have  and if I click on send I should get the token   but let's first try with a wrong password so when  I click on send so here we have our 4403 and here   it's because of this process so we have the token  and then we start the validation process so we   extract the username and password and then we  are calling the user details service to try to   fetch the user from the date database and the  user we got it because the user already exists   but when we move to the security filter chain  and use when we move the security context holder   we will try also to use the authentication  manager to authenticate that user using the   password and the user made that were provided  within the request but this password is wrong   so that's why we are also throwing throwing a  403 as a response okay so now let's test with   a correct password so if I click on send I see  that I have my JWT token I will copy this one   and then I will go back to this get method  I will click again and make sure that it's   always 403 and how we can authorize this  request right now so within the authorization   here within the type click and choose Bureau  token all right so remove or delete if you   have something in here and paste the token that  you just copied Okay now click on send and we   see that we have the message hello from secured  endpoint and we have this 200 okay which which   is compatible with all this process so we have  the filter we validate everything we check the   token user details and then we pass everything  to security context holder we update it and then   our request is sent to the dispatcher servlet hit  the controller and then we get our response pack   so I hope uh this was clear if you have any  questions don't hesitate to drop a comment   and especially don't forget to follow me  to learn more and more about spring boot okie dokie congratulations now you know how  to implement JWT using spring boot 3 which is   the latest version of spring Boot and Spring  Security as well if you enjoyed this crash   course literally just take one second and smash  the like button also if you haven't subscribed   to alibu channel go ahead and subscribe it's  got awesome content around springboot Java   and angular it was a pleasure this is all  for now and I'll catch you on the next one
Info
Channel: Amigoscode
Views: 58,527
Rating: undefined out of 5
Keywords: Spring Boot 3, Spring Security 6, JWT, JSON Web Tokens, Authentication, Authorization, Postgres, Database, User credentials, API, Postman, Security, Java, Web development, Application development, self este, spring boot 3.0
Id: KxqlJblhzfI
Channel Id: undefined
Length: 125min 52sec (7552 seconds)
Published: Tue Jan 03 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.