Spring Boot 3 Keycloak OAuth 2 Tutorial with Spring Security

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
in this tutorial we're going to discuss what is o 2 and how to implement O2 features in Spring boot applications using Spring Security we'll also have a look at how to implement or through patterns for different kinds of applications like serers side rendered applications which are developed using spring MVC single page applications which are developed using Frameworks like angular and also have a look at how to implement machine to machine authorization like in the case of microservices we'll use keycloak as our identity server or authorization server to help do Implement these O2 patterns if you're not aware of these terms o 2 and identity server don't worry we will cover everything in this tutorial so to follow along this tutorial a basic understanding of spring Boot and Spring Security is recommended so without any further delay let's start the video so what is oo 2 the term oath stands for open authorization and it's an industry strandard protocol that was developed for authorization between services or applications and this protocol is right now in version 2.0 that's why is usually known as o 2 let's understand this better with an example so I am a user of a website or mobile application which is an image gallery application this application's functionality is simple the user uploads a photo and can apply different filters and Frames around the photo which here or she uploaded and you can also print these photos so now in recent times everyone is using cloud services to store images like Google photos iCloud or Google Drive so if you want to access the photos which are stored inside your Google account or maybe Facebook account from this image gallery application you have to provide permissions for this application to access your Google or Facebook account you can't just hand over the username and password of your Google or Facebook account to this application because that is very risky as this application can store your credentials to the database and if a hacker gets access to this database you're in trouble so we need a safe way to authorize the image gallery application so that it can access our Google or Facebook Facebook account the oath framework was developed for this reason it's a standard way of providing authorization that means that means permission for a service a in our case the image gallery application to access service B which is a user's Google or Facebook account when the framework was initially developed it was just called as oo but later an updated version 2.0 was released in 2013 so which is called as oo 2 also as I mentioned before the a in oo stands for authorization but not authentication because we are providing authorization for a service to access another service for this reason o 2 is also called as delegated authorization now as the oo concept is clear let's zoom in a little bit and see how the actual authorization flow looks like so we have our user accessing the image gallery application and this application wants to access the photos stored in Google Drive so instead of asking for Google credentials the application will redirect us to the login page of of Google and once we log in we can grant our permissions for the image gallery application to access the Google account thereby the Google Drive account we can also restrict what all permissions we can give to the image gallery application in this example we want the application to only view our photos but not edit or delete them once we Grant the permission the Google server will return a unique access token back to the application and our application can use this access token to access the photos from our Google account once the Google server receives this access token it verifies whether it's a valid token or not if it confirms whether it's a valid token that means a token which is generated by the Google server itself it will grant access to the photos in this way we can only provide limited access to our photos in the Google Drive so that it can just so that the image gallery application can just view our photos but do nothing else and if required we can also revoke the access of this application by changing the settings in your Google account so this is a high level overview of how the o protocol works in the next section we'll have a look at commonly used o terminology to understand this better so we saw on a high level how o works but to implement oath and understand different kinds of oath flows you need to get familiarized with different types of oath terminology the first one is called as a resource or a protected resource in our image gallery application example we saw earlier the resource or a protected resource either image or photos stored inside our Google Drive account so anything which need needs to be accessed by an external service and which needs the authorization to access it is called as a resource the next term is called as resource owner as the name suggests this means the owner of the resource in this case it would be me or you the person who is the owner of the photos the next term is called resource server so this is the server that stores or hosts the resource in our case it's the Google Drive server that stores our photos the next term is called a client which is is the service or application which is accessing the resource in our case it's the image gallery application so this client can be a web mobile desktop application or it can be a standalone service like a micros service or even a device like a smart TV so we also have a couple of categories in clients a client can be a public client which means a mobile application or a web or desktop application and the other type of category is a confidential client so this can be a microservice or a crown job running on a remote server so for each client we have different kinds of authorization flows also called Grand types which means for different kinds of client we have different ways or mechanisms to get the access tokens we will discuss this also in details in the coming sections so the last ter we are going to have a look is the authorization server so this is the server that will generate and provide access tokens to the client and we'll also verify whether an access token is valid or not there are many options available for the authorization server in the market so you have Amazon's AWS Cognito Google's identity platform and Oka as the famous authorization servers if you want to manage the authorization on your own key cloak is a very good option it's an open source offering and in this tutorial we'll mainly see how to implement O2 patterns using keyo so as you understood what is O2 you also need to know something called as oidc also known as open ID connect this is a protocol which is built on top of o 2 which mainly acts as an identity layer so what do I mean by identity layer so previously we saw that when the client wants to access a resource like your photos on Google Drive it needs an access token from the authorization server this access token is basically a random Alpha numerical set of characters which basically does not provide any context or information about the user so which makes it hard for the clients to understand and get the user information for this reason the identity layer will send an additional token called an ID token which contains basic information about the user like email first name and last name so when the user requests a token he or she will receive now will now receive two tokens as part of open ID connect one is an access token and the other one is an ID token the access token will be used to verify whether the user contains necessary permissions to access the user or not and the ID token will be used to verify the user information itself so this is the main difference between o 2 and open ID connect in the later chapters we will also have a look at how this ID token and the access token looks like so you can understand it much better so for now let's move on to the next topic so as I said before we are going to use the kylo authorization server in this tutorial and if you are not already aware of kylo kloo is an open source identity and access management server it's a very popular and widely used authorization server in the industry to get started with keycloak you can download it by going to the downloads page you can either select a standalone installation or Docker download I'm going to go ahead with the standard installation and I already downloaded the kylo software to my machine so once you download kylo uh you have to unzip and open the bin folder in the terminal and to start the kckl server you have to type the command kc. sh start Def and I'm going to provide the argument HTTP Port as 8180 so if you're running uh the command prompt on Windows you have to type the command um let me type this KC dobat start Dev and provide the HTTP Port as again 8180 so once you run this um command the server will run in development mode so we are not creating the server in this production mode but as you are running in the development local development environment I'm starting it in the start Dev argument so you can see that the keylo server is now running on the port 8180 once the server is up and running open the browser and go to the address HTTP Local Host 8180 you'll be asked to create an initial admin user account to get started and access the server just provide a username and password of your choice and click on the create button once the user is created we can log to our authorization server by clicking on the administration console option and now you can see the login page I'm going to type in my admin account credentials and click on login so now you can see that I'm logged into the admin console and the first thing you will observe is something called as a master something called a Master which is the default realm in keycloak so a realm is like a placeholder where you can manage a set of clients users and their rules so each realm is not create is not connected with each other so if I create a user in one realm they are not available or accessible from another realm okay so the first thing we are going to do now is to create our own Realm by clicking on ADD realm button here I will provide a name to the realm and click on create button so now you can see that the realm is created and activated automatically now I can create as many clients under this realm and also as many users and Rule I want under this realm so now let's go ahead and create a client this client is going to be a spring MVC application which is developed using Tim Leaf so this is going to be a server side spring MVC application so to create this client I'm going to click on client section and click on create this will bring up an add client page in here I have to provide the client ID I'm going to provide this as o demo timel client and click on Save now you can see that we see much more details inside the client page so the first option we see is called as client authentication so if you just H over this tool tip you can see the text that uh this defines the type of the oidc client when it's on the oidc type is set to confidential access type when it's off it set to Public Access type so now in this demo I want to create a uh confidential client because this application is going to be a server side rendered spring MVC application which is using time LIF so in this case the client details uh will be stored inside the brow inside the server itself so I'm just going to enable this option client authentication to on we are going to leave the authorization option as off for now coming to the authentication flows we are just going to enable the standard flow here so this is going to be authorization code flow and uh coming to the direct access Grant I'm going to disable this option because uh by using this option the user can directly get a token using the username and password so we don't want to do that in this demo so I'm just going to disable this option and I'm going to click on next and the next field we are interested is the valid redirect URI this will be the redirect URI which the authorization server will use to send us the authorization code as we saw earlier so for this field I'm going to provide the value HTTP Local Host 880 SL login SL2 SL code SL O2 code demo Tim lift client so which is the client ID which we have provided before so this is the default redirect URI which spring boot supports and which is also according to the O2 conventions so this is recognized by our spring Embassy application you don't need to implement this end point spring will automatically handle the request and keycloak will redirect to this particular URI so that's all we need to do now we can click on Save okay now we have to do one last thing inside the client page that is to generate a client secret we can do that by clicking on the credentials tab the client secret was already generated for us so if you need we can regenerate the secret and we will come back to this once we configured our spring MVC application and also we have to create a user so that we can log into to our application we can do that by clicking on the user section on the left side so here we can view all users and also add a new user I'm going to click on add new user and here I'm going to type the username and click on save this will create the user successfully and to set a password I'm going to click on the credentials Tab and in here I'm going to provide a random password Here we also have the option to select whether the password is going to be a temporary password or not if you select this option the very first time you log in it will will ask you to change the password so let's leave this option on and click on okay and set password okay so we installed keylo configured admin credentials created a realm a client and a user so that's all we need to do now let's go ahead and Implement our demo application all right now let's see how the authorization code flow Works in practice we're going to develop a spring MVC application to implement authorization code flow I already have the finished application ready and running so what I'm going to do right now is open a browser window and open the browser Tools in this and the network tab in this way we can see the network calls our application is going to make so I'm going to open the URL HTTP localhost 880 slome as soon as I press enter you can see that an initial authorization request is triggered by the browser to the end port to authorize and if you check the request by we have a response type as code a state parameter and a redirect URI so the kylo server will make a request to this redirect URI after the successful authentication along with the authorization code we'll have a look at it shortly and lastly we also have the client ID as one of the request parameter so as soon as the key clo server received this request it responds with a login page so I'm going to provide the credentials of the user I created in the previous section and observe carefully here right after click on login you can see that we now have a call to the redirect URI as I mentioned before and if you look at the query string parameters you can see the parameters State session State and the important parameter code so this is the authorization code our application will use to request the token now as this is a serers side rendered application I cannot show you how I cannot show you the call to the Token endpoint as it is done in the background by our spring boot application so this is the demo part now let's go ahead to the more interesting section that is for the implementation for that the first thing you have to do is to download the starter code you can find the link to the source code in the description section of this video and once you open the GitHub code you can check out the code and switch to the branch name initial so this Branch contains the B template for this tutorial so we can get started right away and we don't need to spend time in setting up the initial project so once you check out the code make sure you run the class demo application it should be starting without any errors so now let's set up the application the first thing we are going to do is to add the O2 dependency to our spring boot application I'm going to open the pom.xml file and under the dependency section I'm going to add the dependency springbot starter or to client after adding this annotation make sure to refresh the M configuration by clicking on the icon to the top right side corner if you're using intellig so if you if you now have a look at the pal. XML we have dependencies for spring web which will activate the spring MVC module in our project and also the Tim LIF starter which will enable the timel Futures and the last dependency is for testing which we are not going to cover as part of this tutorial however if you are interested I covered this part already in my channel through u a practical example so you can you can have a look at the playlist in the description section now our spring boot application is ready to be configured with O2 capabilities so the first thing I'm going to do is to create a package called as controller under the root project and under this package now I'm going to create a class called as home controller this is going to be the controller which will serve our initial request to the application above the class I'm going to add the controller annotation and inside the class I'm going to create a method called as home which contains the written type as string and inside the method I going to return the string called home this is going to be the name of the HTML file which is going to serve the request no surprises here it's pretty straightforward spring MVC code and lastly I'm going to add the get mapping annotation to the method with the value as home so whenever the browser sends a request to the server with the request mapping home it will redirect the request to the home.html page now let's go to the resources folder and here I'm going to create the home.html file under the template section and this is going to be uh just a boring HTML file nothing special here I'm going to add a H1 tag with some welcome message inside the body tag okay so next we are going to configure the or through client properties inside our spring boot application for that I'm I'm going to open the application. properties file and I'm going to type spring. security do2 do client. registration followed by a registration key I'm going to provide the same name as the client ID we gave before what to demo timel client so you don't need to provide this exact name you can give any name you like and I'm going to add the property key client ID the value of this property is going to be the client ID of the client we created in the previous section the next property is going to be client secret so I'm going to copy the whole property I'm going to copy the client secret from the keylock server and copy it inside the applications or properties file if needed you can regenerate this client secret and uh the next property is going to be scope here you can Define different Scopes and rules if you want to deal with rules in your application by default we are going to have the scope as open ID profile and rules the next property is going to be the type of authorization Grand type which is authorization code which is the present example we are dealing with so followed by the property redirect URI as I mentioned before this is the URL which our keycloak server will call when the authentication is successful we don't need to implement any logic to handle the redirect spring boot security will do this for us out of the box and also this redirect URI is defined according to the O through specifications so all the magic will be done by Spring Security here and lastly we have to provide the property called issuer URI this value you can find it by by going to the key clo URL open your realm settings and click on the endpoint open ID configuration here you can see all the URLs which belong to our realm and uh which are defined as part of the as part of the O through conventions so we have the endpoint to start the authorization flow and the endpoint to get the token for this reason instead of adding all these values one by one we can provide only the issuer URI to Spring Boot and it can refer to this endpoint to make any calls uh that it needs so if it needs to request a token it can call the token endpoint and if it needs to verify the token it can call the introspection endpoint and if it needs to get the user info it will call the user info endpoint and so on and so forth so I'm going to copy this value and paste it inside the application. properties file so that's all we need to do to configure the O2 client properties in our spring boot application so we provided all the necessary information now let's start our server and open the URL HTTP Local Host 880 slome again so you should be redirected to the keycloak login page I'm going to type in my credentials and login pkc authorized code flow spelled as pixie authorization code flow stands for proof of key code exchange authorization this grant type was created to be used for public facing clients for example web applications which are developed using JavaScript Frameworks like angular react or View and also mobile applications the pixie authorization code flow is mainly considered as a best practice to follow when we are using public clients the main reason for using these kinds of uh different authorization code flow is because if you remember as part of the authorization code flow we saw previously that to get the access token and ID token pair from the authorization server the client needs to make a post request with the client ID client secret and the authorization code so that means we have to store the client secret somewhere in the client to be able to make a post call for the token endpoint this is very risky because any web developer can view the source code of the JavaScript applications and find the client secret if you store it in the client so the same also applies for the mobile application so if you have the APK file and uh you can decompile or uh decrypt decompile that APK file to view the source code so it's not safe at all to store the client Secret inside the client source code so for this reason a new type of authorization code flow was designed which is the pixie um which is the pixie enhanced authorization code flow this flow is very similar to the authorization code flow but with a couple of additional steps and also there is also no need to maintain the client client secret anymore in the client by using this approach as I said before so let's see so let's go ahead and see how it looks like the pixie authorization code flow similar to authorization code flow we'll make an initial request to the authorized endpoint of the key clock server with some query parameters parameters we are sending are almost similar to what we sent as part of the authorization code flow so if you need to understand why we need these parameters have a look at part one of this video I'm not going to repeat this information again so as part of the pixie authorization code we are going to send two additional URL parameters the first one is called as code challenge which is a base 64 encoded random string which is generated by hashing and encoding another value generated by the client called as code verifier the next parameter is called as code challenge method which should be configured inside our authorization server when we are first configuring the client the recommended value for this code challenge method parameter is s256 which is a cryptographic hashing function once the clients make this request to the authorization server the server responds with the login page asking for the user to authenticate once the user logs in the authorization server returns an authorization code similar to the authorization code flow we saw in part one of the series but now to request an access token the client should send the code verifier value along with the authorization code as part of the post request to the Token endpoint when the authorization server receives this post request it validates the the authorization code and the code verifier values and then responds with an access token and ID token pair once the client gets this token it can now make the request to access the resource to the resource server and the resource server will first validate whether the token is valid or not so this is how the pixie authorization code flow Works hope you have understood this Theory now let's see this Grand flow in practice and then implement it using spring Boot and an angular application okay okay so now let's see the pixie authorization code flow Grand type in practice for this I already started the front end and backend applications and in the browser I have the network tab open and I'm going to hit the endpoint Local Host 4200 and in here you can see the Link login if I click on it you can see similar to the authorization code grand type we had the we have the initial authorization request to the key clo server which returns a login page if you check the parameters which are of the authorization request you can see the response type as code the client ID and a state parameter the additional parameter added to this request URL is the code Challenge and code challenge method these values are generated by our Ang application and the keylo server responded with a login page for this request now let's go ahead and login I'm going to type in my credentials and click on login button now you can see the request which is made to the redirect URI if you check the query string parameters again we see the the same query parameters as the previous authorization code flow we have the state parameter State session and code our angular application will use this code to make a post request to the Token endpoint as this is a public angular application so if we have a look at this request it goes by the name token so it's easy to identify and as I mentioned before this will be a post request with with request body as the authorization Grant type the authorization code the redirect URI and client ID lastly we have a new parameter called code verifier this value is used to verify the code challenge method the code the value code challenge just as explained in the previous section now if you check the response of this call you can see the value for the access token the expiry time of this token followed by the refresh token and it's expired time so if a client needs to make any calls to a resource server it can make use of this access token and if the client and if the access token is expired it can use the refresh token to request a new access token now this is how the pixie authorized code flow works so let's go ahead and see how to implement this grant type okay so first of all we are going to start by creating a client inside keylo for that make sure you have the keylo server up and running and open the address Local Host 8180 and login with your admin credentials now if you click on the clients Tab and click on create button we're going to provide the client ID as o through demo pixie client and click on Save and now here we have to make some changes so I'm going to leave the client authentication as off so if you see select the tool tip here uh we have already saw we already saw that if our oidc client is of uh public then we have to switch the toggle off and uh the uh in for pixie uh authorization code flow our client is going to be an angular application so for this reason I'm just going to leave this client authentication as off and coming to the authentication flow itself I'm going to select the standard flow which is indeed the um which is indeed the authorization code flow and I'm going to uh deselect the direct access grants one more time and I'm going to click on next here and we have to provide the value for valid redirect URI so this is the URI where the authorization server will send the authorization code and the client reads the code so I'm going to provide here the value Local Host 4200 which is the address of the angular application the next value we have to provide is for the web Origins so this would be the allowed course Origins which can access the authorization server so we are going to provide a star here as we are going to permit all Origins so when you're using this for production applications please don't provide a star value here and only provide the valid origin of the redirect URI you're are going to use so that means if your frend application is running on a server provide the host details of the server instead of allowing all Origins all right so the next value we are going to configure is the pixie enhance code challenge method you can find this value under the advanced settings and I'm going to select the value as s256 which is a cryptographic hashing function which will be applied on the code verifier value so if you select plane there won't be any hashing performed on the code verifier and this is not a secured option and this is highly discouraged so that's it for the client configuration I'm going to click on save so now let's go ahead and dive into the code so similar to part one of this video you can download the starter code from the GitHub repo you can find the repository in the description section of this video so the main branch contains the completed code and the starter code is provided in the initial Branch so if you struck for any reason you can refer to the completed code in the main branch so in this video we are mainly interested in the pixie authorization code flow so once you open the O2 pixie demo project under the source main resources folder you'll see a folder called front end which contains the code for the Ang application so the first thing we going to do is to install a package called angular O2 oidc inside our angular application this package will provide o through capabilities for our angular application by just writing some minimal code so this package supports both authorization code flow and pixie enhanced authorization code flow so let's go ahead and add these details inside the package.json file so at the time of creating this video the angular O2 oidc package is on version 10.0.3 so once you have added this dependency run npm install to download and install the package to your machine okay now we have to configure the client details inside the application for that I'm going to create a new file called O.C config.txt const o config and declare the return type of the object and inside the object I'm going to Define six Fields the first one is going to be the issuer URI so if you have watched the part one I already discussed what is issuer URI in detail so please have a look at this video if you didn't watch it yet so this issue URI contains all the list of configuration endpoints which is exposed by the authorization server so you saw in the theory part that our client is going to make multiple calls to the authorization server the first one is the initial author request and followed by the token endpoint request and subsequently it will also make a request to refresh the token if needed so instead of hardcoding all the endpoints in the application you can just provide the issuer URI which will expose the list of endpoints and then the client can use this list of endpoints and and call whatever uh endpoint is required okay the next value is going to be redirect URI this is the same value we provided when configuring the client in the previous section so instead of hardcoding this value inside our code we can provide the JavaScript window object like window. location. origin which will return the address of the web application the next value is going to be the client ID which is O through demo pixie client again we have to provide the same value as we provided inside the client so it's better to copy this value from the client information in keycloak and paste it here the next value is going to be response type this is going to be code as we are following author code flow mechanism even if it's pixie enhanced we provide the value as code itself so the next value is going to be strict Discovery document validation so this is something which is relevant to this angular or to IDC Library so we are going to provide it as true so this is used when the list of endpoints exposed by the issuer URI endpoint does not contain the same base URI as the issuer endpoint so what do I mean by that so if I open the open ID configuration of a realm you can see that by visiting the realm page inside our key clo server and click on open ID configuration link you can see that the base URL of all the URLs are same because we are using keycloak as authorization server it is going to be consistent so if for any reason we anticipate the base URL is not going to be consistent across all these URLs then we'll provide the value as false so in those cases our application will not validate the discovery document that is the Json seeing we seeing here for the base URLs all right moving ahead we have the last parameter called scope here I'm going to provide some default Scopes like open ID profile email and offline access after configuring these values now let's implement the flow it's very easy I'm going to open the app component HTML page and remove all the default HTML which exists inside the file and I'm going to replace it with just some barebone HTML code so I'm going to to add an anchor tag with text called login and another anchor tag with text log out so if I click on this link in the browser it should make the authorized call to the authorization server as seen in the theory which is step one so to do that I'm going to make use of the outof thebox functionality provided by the angular a to oidc package so I'm going to first inject the all service class into the component which is coming in from the library make sure to import the class into the component and after injecting the service we should provide the O config details to the service we can do that by first creating a method called as configure so let's define and create this method and inside the method I'm going to type this dot what service. configure and passing the O config object as the argument also make sure to import this object into the component now I'm going to type this. O service. load Discovery document and try login so what this method call will do is to make a call to the issuer URI and get all the necessary endpoint required to trigger the login flow okay now we are ready to trigger the login flow for that we can make use of the convenience methods provided by the angular or to oidc package for that I'm going to create two methods login and log out so first inside the login method I'm going to type this do all service. init code flow which will kick off the authorization code flow and inside the log out method I'm going to type this do what service. logout which will take care of logging out of the application automatically so you see how it is how easy it is to implement Au authentication and authorization using this Library so it makes our life easier as the developers and if you want to implement it manually so it's going to take lots of time and effort to do it so due to this flexibility provided by the libraries it's important for us developers to to to due diligence and understand how it's working under the hood so that's where the videos like this are going to help you so if you like it so far don't forget to like the video and subscribe to our channel to make uh to check out more interesting tutorials like this all right now let's come back to our tutorial so we configured the required methods inside the app component typescript file but we are not yet calling these methods from our HTML file so let's open the app component HTML and call the login and logout methods when clicking on this link so I'm going to use the click directive and pass in the login and log out methods method definitions there so now if I click on the login link from the browser it should kick off the pixie authorization code flow mechanism all right now let's start up our angler application for that I'm going to type npm start in the terminal and make sure you are in the front end directory and once the application is started up open Local Host 4200 so now you can see that we don't see any um any links here any hyperlinks with login or log out because we have an error because the O servers is not understandable by the angular modules for angular application this is because we have to define the O module inside the op app modules. TS files so I'm going to open the app module. TS file and in there I'm going to inside under the import section I'm going to type O module. for Boot and inside here inside the configuration section I'm going to provide the object for resource server and inside there I'm going to provide what are the allowed URLs for the resources server so this is going to be HTTP Local Host 880 / API we did not yet create the resource server but we will do it shortly you will have a look at it shortly and the second um and the second variable is going to be send access token true so we are also going to see in detail like what is actually this mean this particular variable and declaration means so now as we've done that uh we will also Define the HTTP client module because we'll make a call to the resource server and we need access for the HTTP client to make a get request so in this way we are covered also for the HTTP client module to be accessed from our angler application so once you've done that uh you can restart the angular application and uh open the browser again the Local Host 4200 and refresh the page and now you can see two text values login and log out and I'm going to first open the dev tools and network tab so you can see the network calls while logging into the application click on the link login it will open the login page and as part of the first request you can see the value code challenge which is generated by the angular or to oidc package and we are also sending the code challenge method as s256 which is the same value as we configured inside the key clo uh client so the rest of the query parameters are similar to the authorization code flow and uh coming back to the browser window I'm going to type in my creden shells which I created in part one of the series and once I click on login and if we check the network tab inside the dev tools again you can see that it made the call to authenticate followed by the open ID configuration call so this is the Discovery document which is returned by the authorization server so if you see the response you can see all the information we saw before here and uh the client will make use of this data to make a token endpoint post call to the authorization server so you can see that Al so you can also see that it sent the grand type as code the authorization code it received from the keycloak the redirect URI the code verifier which is generated by the angular o to IDC package and the client ID so once the kylo server receives this request it will decode the code challenge value provided as part of the initial request so you can see here in the diagram in Step One using the s256 cryptographic hashing function and verifies whether it's same as the code verifier or not if yes then it will respond with access token and ID token and uh the token value is stored inside the session storage by default as I'm using an an incognito window so you can use this access token to request the resource server and access is the protected resource so this is how we Implement pixie authorization code flow on the client side now let's implement the resource server part so if you go back to the source code we have our springbot application which just contains a main class as of now so to configure the resource server we have to First add some dependencies to enable O2 resource server capabilities for that I'm going to open the pom.xml and add in three dependencies the first one is going to be springboard starter or to Resource server which will enable the resource server capabilities inside our springbot application followed by Spring Security or to Jose dependency which will also enable the JavaScript object signing and encryption framework shortly called as Jose framework which is used to securely transfer claims between two parties this means transferring the Json web tokens the Json web signatures Json web encryption and Json web keys so I'm I'm not going to go over this in details but in a nutshell it makes sure that the keys and tokens are transferred securely between two parties lastly I'm also going to enable Spring Security in this project using the spring board starter security dependency after adding all these dependencies if you are using intellig as your ID make sure to click on the maven icon on the top right corner to force intellig to download the dependencies now it's time to configure the resource server properties for that I'm going going to open the application. properties file and Define a property spring. security. through. resource server. jw. JWT set URI so this is the property which will point to the key set Ur of key cloak which is used to verify the access token and ID token we receive from the client here you can see this in the diagram in step 7even and 8 for this I'm going to open the open ID configuration of the key server by opening the realm and clicking on the open ID configuration link and I'm going to copy the value for jwks URI and paste it inside the file okay we have configured the resource server now let's create an endpoint to act as a resource for that I'm going to create a package called as controller and inside the package I'm going to create a class called as home rest controller as this is going to be a rest controller I'm going to add the rest controller anot ation from Spring MVC followed by the request mapping I'm going to expose the endpoint at/ API slome and I'm going to also configure the cross Varin annotation with value as star so inside the class I'm going to create a method called as home which returns a string and inside this method I'm going to return a string called hello as this is going to handle a get request I'm going to add the get mapping annotation followed by the response status annotation with value as okay all right we configured also the endpoint and the last thing which is remaining is to configure also the Spring Security for that I'm going to create another package called config and inside this package I'm going to create a class called as security config all right so inside the security config class I'm going to first create a bean so I'm going to add the bean annotation and this Bean is going to be of type security filter chain so I'm going to type in security filter chain and I'm going to provide the method name as security filter chain and uh I'm going to provide the method argument as HTTP security and inside this um Bean definition I'm going to define the HTTP security do course settings and in this course settings I'm going to add uh make I'm going to ask Spring Security to use the default settings for that I'm going to type in customizer dot customize customizer do with defaults and uh so looks like the course method is is going to throw an exception so I'm going to add um throws signature on top of the on of for my method and after that I'm going to add the settings for cross site uh request forgery so I can do that by adding csrf and inside csrf uh for this csrf usually um you see that for rest apis we disable the csrf but this is not really uh uh this not really applies for all the cases so for this reason I'm just going to Define csrf uh as csrf do ignore request matchers and I'm going to provide the request matcher as SL API slome slst so what this will do is whenever Spring Security uh recognizes that receives a request at pa/ API slome then it will not check for the csrf token for that request for all other request it will check for the csrf token and uh so whenever if you want to use cookie uh authentication in the future then your rest API is uh secured with csrf capabilities you don't need to worry about including the csif capabilities in the future so the next part is going to be going to be about authentic authorization so we're going to configure our Spring Security application to authenticate all the requests all the incoming requests right so for that I'm going to type authorize HTTP request and inside this I'm going to type in HTTP requests and I'm going to type in HTTP requests. any request. authenticated and uh so the next thing I'm going to do is to define the session management so for that I'm going to do type do session management and I'm going to Define session do session creation policy and I'm going to Define it as stateless so session creation policy as stateless because as we are using a rest API we don't expect uh our applications to maintain any state so because um rest apis are by definition stateless so we're going to define the session management as stateless and the next thing is going to be I'm going to define the uh resource server capabilities in our security configuration so for that I can type uh I can type do o res o to Resource server and I'm going to type in o 2 resource server uh and I'm going to Define or2 resource server do JWT and inside the and here I'm going to also Define uh customizer do with default so that the default configuration for JWT is applied to the resource server and after that I'm just going to type do build so now this configuration will build an object of uh security filter chain so I'm just going to add a return statement and now we are done with the security configuration for our resource server so now let's go ahead and start our angler application so the on the backend side all the configuration is completed so let's go ahead and run our front end application and test this functionality all right so now I'm inside the angular application inside the terminal I am going to first create a service class which contains logic to make calls to our resource server for that I'm going to type NG GS app which is going to create a class called as apps service.ts and appservice dope. TS files we are only interested in the app service.ts file right now so I'm going to open this file and in here we have to make a HTTP get request to our resource server for that I'm going to first inject the HTTP client into into the service and after that I'm going to create a method called as hello which will return an observable of string as we are returning a string as a response from our back end inside the method I'm going to first Define HTTP headers by setting the content type as text or plane the reason being as I mentioned we are set we are returning a string as a response now I'm going to make the get call using the HTTP client to the URL Local Host 8/ API SL home and now we are going to pass in the headers as the next argument for the get method so when the HTTP client makes a get call to this URL it will include these headers and also make sure to add the written statement so that it will return the observable so we implemented the service call so what is remaining now is to call the service from our component so for that I'm going to open the app component typescript file and in here the first thing I'm going to do is to inject the app service class and inside the Constructor I'm I'm going to call the hello method from the app service and subscribe to the observable returned by the method inside the Subscribe method I'm going to read the response and assign it to a variable called text let's store this subscription inside a variable called hello subscription which is of type subscription and we have to unsubscribe from the subscription when the component is destroyed so for that I'm going to implement on Destroy interface for this component and inside the NG on Destroy method I'm going to type this do hello subscription. unsubscribe this will make sure that there are no active subscriptions lying around which can cause memory leaks in the application if not given sufficient attention all right the last and final thing we are going to do is to bind this variable to our HTML page so for that I'm going to add in a H1 tag and bind the text variable as I don't want to write much code and keep this video relevant to o 2 and klock to display the response from server we have to refresh the browser after the login so I'm going to add in the message also here okay so we completed the implementation part on the front end as well as the back end now let's start our front end application by typing npm start and make sure that the backend spring boot app is also up and running all right now let's open an incognito window and open the address Local Host 4200 and click on login now I'm going to type in my credentials and after clicking on login you can see the homepage so let's refresh the page and you can see the response from the back end as hello now you may ask how did our angular application recognize the token and send it part of the request to the resource server automatically so this is done by the angular O2 oidc Library automatically so that is one less thing for us to Care as the developers the client credentials Grant flow is mainly used for machine to machine authorization which means if the client is a CLI application or a shell script running on a remote server or even a spring boot microservice it doesn't make sense to use a standard username password combination with the login page like how we implemented in the first two parts of this series using the authorization code code flow Grand type or pixie enhanced authorization code flow Grand type for this reason when using this flow the clients will directly make a post request to the authorization server with grand type as client credentials and it and it will also include the client ID and client secret to authenticate themselves with the authorization server the authorization server will validate the credentials and if they are valid we generate an access token and sends it back to the client when the client needs to access the the protected resource similar to the other Grand types it will include the access token as part of the request header and then the resource server will verify the validity of the token by sending the access token to the authorization server you may have already observed the client credential flow is significantly simpler compared to the other two authorization code flows that's because uh of the confidentiality which is enroled uh based on the client so now let's go ahead and see a demo on how to implement this Grand type so I have a springing boot application up and running already and now I opened a rest client like Postman to make a post call to request the token from the authorization server so here is the endpoint to which we are making the request you can get this endpoint by opening the realm settings inside key clo and clicking on the open ID configuration link and by copying the token endpoint from the Json back to the postman client as part of the post request I'm passing the request body with the first field as Grand type which is going to be client credentials followed by the field client ID I'm going to provide the client ID as o to client credentials I already created a client inside keycloak with this client ID I will show you how to create this client also shortly the next field is client secret which is an autogenerated Secret by the kylo server so now if I click on send you can see that we received the access token and we can now use this access token to make a request to our resource server okay I hope you understood how we can request a token from the authorization server through this demo now let's go ahead and see how to implement the client credentials Grand flow in a spring boot application all right so now I'm inside the client section of the watch to demo realm and I'm going to create a new client here so that so I'm going to click on the create client button and for the client ID I'm going to provide the value as Worth to client credentials and I'm going to click on next and here as we want to implement the client credentials Grant and In Here Also the client is going to be of type confidential I'm going to toggle on the client authentication and I'm going to disable the authentication flow standard flow and I'm also going to disable the direct access Grant and I'm going to select the option service account rules so if we just click on the tool tip here you can see that it allows you to authenticate this client to keycloak and retrieve access token dedicated to this client in terms of all specification this enables support for client credentials Grant so that's what we need so that's why I created I check this option service account roles and I'm going to click on next and I'm going to click on Save you'll see the credentials tab if you click on it we can see a client secret which is generated already for us just copy this value we will use it in our spring boot application later so we completed the keylo configuration part now let's go ahead and implement the spring boot configuration part for that I'm going to open our initial starter project on GitHub so you can download this project from the GitHub Link in the description section and make sure you are on the initial Branch to code along and follow the tutorial so in this part we are going to mainly focus on the watch2 client credentials demo project so if you open this application in your IDE you can see that the application is just a plain old spring boot application with the name of microservice application so now let's configure this application with the client credentials flow so for that the first thing we have to do is to go to the pom.xml file and here we have to add the security capabilities for our application we can do that by adding the security starter dependency from uh string boot so I'm going to do that by adding a dependency inside the dependency section so the name of the group ID is going to be org spring framework Boot and the artifact ID is going to be spring boot SEC starter security so once this is done let's uh click on this load Maven changes icon so after that I'm going to add one more dependency called as spring boot starter W to Resource server so I'm going to replace the security with W 2 resource server so as we saw before uh while showing as we saw before in the pkc demo uh we are going to configure our client credentials as a resource server and um as a resource server so for this reason we've added this uh dependency spring board starter or through resource server so again let's load the changes from Maven and uh once this is done uh we are ready to to configure our application with the client credentials so the first thing I'm going to do is to create an endpoint in inside this application so I'm going to right click on the root package and click on new Java class and I'm going to call this as hello controller and let's create this class in a new package so I'm going to add the also the package name before the class name so in this way intell will automatically create a package called as controller and we'll uh keep this hello controller class inside this controller package so the next thing I'm going to do is to create add the rest controller annotation and followed by the request mapping annotation let's um expose this request mapping let's give a value as/ API you can already see that I'm using uh GitHub co-pilot and it's giving me some suggestions so this is Handy um so I'm just going to make use of this suggestion what I want to have is um a get mapping not a request mapping for a endpoint called as hello and I'm going to have uh I want to have a method called as hello which returns a string and inside this method we have a body called as hello from microservice right so this is uh the May minimum we have we want we want to have to test this uh to test the client credentials um so this is the end point we want to have and the next thing I'm going to do is to create the security configuration so for that I'm going to create a new class called as security config and I'm going to uh organize this inside a package name called as config so I'm going to type config do security config and here we have to provide the security configuration to to enable the client credentials for so for the first thing I'm going to do is uh I'm going to add the configuration annotation and I'm going to uh copy the configur security configuration from uh O2 pkc demo so I'm going to expand the O through pkc demo project and I'm going to go to the security config class and what I'm going to do is I'm going to copy the whole class the content inside the class uh WR up to the import statements because I can use everything as it is so I'm going to go back to the security config in the client credentials demo project and I'm going to paste this right until the import section so now we have all the required configuration here so just as a recap we have a security filter chain Bean uh which is the main entry point into while configuring our security configuration in our application and inside that we are uh first of all using course with defaults um now as uh in pkc demo AS application as a resource server is being accessed by an Ang application we were uh enabling course but as this this is a client credentials uh this application only uh deals with client credentials that means uh this application will be accessed only by some API clients or maybe another microservice we don't really need to enable course so for that what we can do is uh we can disable course by by typing course. disable so I'm going to inline this uh Lambda expression with uh method reference uh and uh next we have csrf and again is the same case as this is completely accessed by uh another API client or maybe another microservice we can also disable csrf I'm going to uh replace this ignore request matchers with the method called disable and I'm also going to inline this uh Lambda with the method reference and uh we can keep uh rest all configuration as it is so we are going to authorize all the requ all the incoming requests using this HTTP request. any request. authenticated method and uh coming to the session management we are still uh want to have stateless session in your our application because this is a rest API and finally we are going to enable the war through resource server capabilities using the JWT method and by providing the default configuration so let's uh now deal with the configuration part in the application. properties file so I'm going to open the app and here we need to add a property for Json web key set URI and so we can uh look this up from the again we again we can look this up from the W2 pkc demo project I'm going to go to the application. properties file and I'm going to copy this whole property which is defined inside the application do properties and I'm going to paste this inside the application do properties of client credentials demo project and lastly I'm going to just to be sure that we don't use the same existing Port I'm going to add the server. port as 8083 so once this is done we can start up our application and we can test the client credentials SC type all right so I opened the postman client and in here I've already configured the URI of the endpoint which we have created before so I'm trying to call the Local Host 883 API /hello endpoint so this is going to be a get request and uh we have to add the uh jot token to our authorization headers so for that I'm going to open the authorization header Tab and here I'm going to request a token from Key clo to start the client credentials grand grand type so for that I'm just going to scroll down until the configure new token section and in here I'm going to provide the client ID of the client I've created in the previous section and I'm also going to provide the client secret so let me show you how to get the client secret if I open kyck CL here and I'm going to open the client which I've created uh before so this is going to be over to client credentials and in here I'm going to go to the credentials Tab and I'm just going to copy the client secret and then paste it here and now I'm going to click on the button get new access token and now you can see that I received a new access token and I'm going to now click on the send button and you can see that we received the response hello from micros service so let's try to tamper with this token so I'm just going to delete a part of this token and then try to send another request to test if if our endpoint is really secured or not so I'm just going to press the send button again and now you can see that we are getting a 401 unauthorized error so I hope the client credentials grant Grand type is clear for you so that's it for this video I hope you learned about key clo and how to implement different types of grand types using key cloak so I'll see you in the next video until then happy learning teis
Info
Channel: Programming Techie
Views: 28,977
Rating: undefined out of 5
Keywords: spring boot 3 keycloak ouath2, spring boot 3 keycloak, spring security oauth2 keycloak, spring security6 keycloak
Id: _0oXZKr97ro
Channel Id: undefined
Length: 65min 0sec (3900 seconds)
Published: Sun Oct 22 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.