How to secure SpringBoot REST APIs using AWS Cognito OAuth2 scopes?

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hi welcome to my channel and thank you to my subscribers if you have not already subscribed to this Channel Please Subscribe in this video we are going to see how to secure the apis that are exposed in a springbot app using the AWS Cognito oo2 score SCS so before going into the stepbystep configuration of how to build a spring boot app from scratch and then secure its API using AWS Cognito or through Scopes let's quickly go through this very basic diagram so that you will understand how the end to end flow works so if you look at the very first step you have a client application and that client application can be in any app it can be a UI app a front-end app or it can be a backend client application which is calling apis or it can be a mobile app which is calling apis that are exposed in a springbot app so it can be any application so The Client app is basically the client which is calling the apis that are exposed by the springbot app and when this client application is calling the apis exposed in Spring boot app it needs to pass a token which will be validated by the spring boot app in order to allow or deny access so the way this flow works is The Client app will first call the Cognito token end point using the client credentials Grant which is one of the O 2.0 grants and you can go and check the O2 spec for this Grant and you uh go through all the flows so when when the Client app calls this Cognito token endpoint using the Cent credentials Grant it will get a JWT access token and then it can pass this access token in the header to the spring Boot apis and spring boot will validate the token in the step number four and uh and also the scope and then based on the validation if all the validations are successful then it will return return the response API response with a HTTP 200 but if the token is invalid or if the token already expired then the spring boot application will return a HTTP 401 response at the same time if the token is valid but the token doesn't have enough permissions to call the API so for example the client application is having a valid token but it is not allowed to access one of the apis that is hosted in the spring boot app like for example let's say there is a get user API and there is a right user API but the client application is allowed to call only get user but not WR user so when it passes the token to the spring boot app the token will be valid but the poins the token doesn't have permissions to call that right API so what spring boot app will do in that case is basically it will return a 4 03 forbidden error so we will look at all these scenarios like we are going to build this entire app from scratch and we are going to provision a new Cognito user pool for this app and see how to configure configure The Client app in the Cognito user pool and then call the apis that are hosted in the spring boot app so in order to do that I'm going to use the AWS console the Cognito service where I will be creating a totally new Cognito user pool and for the Java springbot app I'm going to use the spring tool Suite ID and you are free to use any ID that you are comfortable with like Eclipse intell J or any any other ID that supports spring framework I use this ID because it's it comes from the spring framework world and it has very good support for spring boot projects so now let's start with the very first step of creating a Cognito user pool and then we will go ahead and uh create a client application the spring boot application using the spring tool suite and then see how to secure those apis using Cognito Scopes so let's create a new user pool I am not going to go through each and every configuration available in this spring boot user sorry in this Cognito user pool you can explore that later let's quickly create a basic user pool that is required for this integration so select username go to next we don't need MFA for these use cases uh disable this go to next disable this disable just select this one just to go to the next screen and now we need to enter a user pool name I am going to name it as spring boot spring boot Cognito RS which means resource server and we don't really need a hosted UI in this case but let's just select it that's fine uh sorry I I will take it back we actually need the Hoster UI because Hoster UI is the one which supports all the o to service end point so we need to select Hoster UI and let's name it as ISP Cog RS yes it is available so you can give any name here as long as it is available so if it is not available just try typing Cog rs1 Cog rs2 whatever you want and now let's actually create a confidential client name it as ISB Cog client and we need a client secret and let's go to the advanced app client settings let's leave all these things as is because we are not going to use this client anyway I'm going to create a totally new client so let's leave this client just give some dummy URL here for call back URLs because uh I think it will throw an error if you don't give an URL click next review all the settings create the user po so this is the user pool that we created you can go to the app integration tab you can check that Cognito domain you can even see the client that got created but anyway ignore this client we are not going to use it I'm going to create a totally new client so that you will understand each and every step when we create a new client for for securing the apis so now let's go to the spring tool suite and start creating a new project from scratch and expose an API through the spring boot app and then see how to secure that API I already have a project I'm not going to use it I'm going to create it from a scratch so before creating the project let's actually open the springboard O2 security docs so just search for springboard O2 security in Google and this is the link which explains all the O2 security features that are available in springboat out of the box so in this case we are going to look at how to secure the apis so we need to use this o to Resource server capabilities that are available in springboard and we are going to use this JWT option which actually uses the O2 Scopes so let's actually go through these steps I will create a totally new project from scratch so let me actually I will switch my workspace so I will call I will create a totally new workspace called Cog RS demo so as I said earlier you are free to use any ID as long as that ID is supports Java spring boot development you are free to use any ID whichever you are comfortable with uh you have to just make sure that all the springbot libraries that are required for this particular project is properly added in the Mayan configuration file I'm going to use the Mayan build so let's see how to do that so from this ID select create new spring starter project name that project as SB Cog RS select may go to next and here select search for security and let's select Spring Security O2 client or to Resource server and search for web and select spring web finish and this will create a totally new project from scratch and let's see what all things are created so it created a main application class which you can see here and this is the main spring boot application class it also created an application. Properties by default let's actually change the extension to application. EML excuse me uh so you can use application. Properties or application. EML format I am comfortable with the EML format so I am renaming it as EML if you're comfortable with the properties format that is also fine so now let's go ahead and create a API in this springboard application so how do you create a API so let's create a totally new class called user controller so in order to expose an API in springut you need to annotate that class with rest controller so if you type rest controller and you can import yeah so you can import risk controller so once you anotated class with rest controller I will actually remove one you can create methods like this and that will automatically get exposed as an API so I'm going to create an method called get user the these are just going to be dummy apis I'm not going to add too much of business logic here so the way I'm going to do is just I'm going to return return message called access granter reading user details right and I'm going to make it as a get API and I'm going to give the path as SLG user so this is an API so here you can add any business logic you want like uh reading from a DB based on some parameter that is passed Etc I'm not going to go into all those details because the main goal of this video is to see how to secure this API so here so now let's actually see what happens let's start this application so right click this main application class and run it as a Java application so the application started in Port 80 and I'm going to use Chrome uh sorry post Postman for testing this so if I go to http SL Local Host call 880 get user Clicks in I get a 401 unauthorized which means this API is already secured secured but we don't don't know which token is used for securing this API that is something we need to still configure in this application. ml but this API is already secured by default and you know why it happens that is because of these dependencies when you add spring boot security dependencies to your may1 pom.xml by default it secures all the end points in your application now let's let's see what happens let me actually comment out all these some of these uh security related dependencies and just see what happens we we will anyway revert it back this is just for your understanding that I'm doing it but you we will rward all these comments like we are not going to comment it permanently so I commented all the O2 and security related dependencies and I have only the web dependency here let's restart this application and try to access the same API and see what happens now when I access it it gives me a 200 response with whatever message we WR in that API which is access granted reading user details so so this is the beauty of the spring framework so it I'm going to uncomment all these things undoing all these things so it automatically secures all the endpoints the moment you add these security related dependent libraries and now I get a 401 okay so now let's go ahead and configure the Cognito related details in this application EML so that uh this particular API will be secured using the Cognito O2 token that is generated using the user pool that we created in this very first step but before doing that we need to create some configuration in this Cognito user pool so let's quickly do that so in order to create custom Scopes in cognito user pool you need to create a resource server like custom Scopes is basically the o or 2.0 Scopes so let's call this resource server so this resource server actually represents the API that we are building in the spring board tab so let's name it as spring boot which is SB user API and let's give an identifier called Spring boot user API and let's add a custom scope called read user and description as read user details and create the resource server so the resource server got created SB user API now let's create a client confidential client and let's name it as SB user client and you need to select generate a client Secret in case it's not selected by default and let's go to the o to Grand type and select client credentials and for the custom Scopes select the SB user API SL read user and if you try to create actually it will give an error uh that is because the call back URL is a mandatory field but anyway it is not used so just give some dummy URL here and create the app Cent so the SB user Client app Client app got created in cognito now the next step is to see how to get a token using these client application credentials so in order to do that go to Cognito token in point documentation search in Google for Cognito token endpoint and the very first link takes you to the Token endpoint and here you can go through the details like what all parameters you need to pass to the O2 token endpoint in cognito I will quickly explain how to do that using Chrome so in order to call this o to token endpoint we need the Cognito domain so this is the domain in my user pool in your user pool it will be a totally different domain because it is unique per user pool so copy this domain change this to post paste it here go back to the documentation copy this/ O2 token append it to this domain so now we need to actually pass certain parameters in order to get a access token using client credential stand the very first and these are all based on o 2.0 spec which you can go through in you can search in Google and go through the spec so you need to pass Grand type so select body X for WW form URL encoded Grand type as client undor credentials and for the client ID secret go to the authorization tab in your Postman and select basic cod and I'm going to delete the old ones and let's again go back to my Cognito user pool and this is the SB user client just we will verify it once yeah this is the one copy the client ID and copy the client secret and that's all we need to just pass a grand type as client credentials and then the authorization header and then hit this URL and you will get an access to so you can check this access token details go to [Music] jw. and do this so you can see the token details here and here is the scope read user so now we have the token now what we need to do is go back to the spring documentation and here you can see in order to specify the issue the token issuer details in the spring boot application yl file you need to specify these parameters in the spring boot application EML file so copy this go here and just paste it here the only thing we need to modify here is the issuer URI so this issuer URI should point to the Cognito user pools issuer URI which is my Cognito user pools issuer Ur So now let's see how to get that issuer URL dri value from my Cognito user pool so again go back to Cognito documentation and here select hosted UI and points reference sorry Federation and points reference and copy this well-known open ID configuration paste it here and we need to replace certain values like region and your user pool ID so my user pull ID is here copy it replace and my region is usph he Ty one if you have created your user pool in a different region just make sure you give that particular region here otherwise it won't work so now press enter so you get certain attributes here like issuer authorization and point all those things so copy this issuer go back to your spring application and paste it here that's it so the end to end setup is done it's it looks very simple but that's the beauty of spring frame spring boot framework that it does many of these things which we saw in this diagram like validating the token all those things is automatically done by the spring boot framework you just need to specify the issuer URI in your application EML and pass the token that is generated but by that particular issuer which is my Cognito user pool and then it will like magically do all the authorizations it will perform all the security checks and make sure your API is secure now let's restart this application and let's go back to my Postman again hit that same API and I should get a 401 which is expect VOR now go to headers and pass that access token which is generated by my Cognito user pool in the b in the authorization edit so you the way you need to passess in the value you need to specify barer space that access token value now when I hit I get the user details you know how that is is because springo app is now accepting this access token that is generated by this particular Cognito user pool because I configured that cognitive user pools issue or URI here let's just try a different thing so for example here I said if you pass a invalid token it will give a 401 error right so in this token just delete one of the characters so that it will become invalid let's see what happens you get a 401 unauthorized error that is because it's a invalid token now I undo the change and again click Send I get a grant reading user details so now now the API is secure like whatever API you built here is now secured now let's do a minor enhancement to this particular logic and see what happens so right now it is only checking the token it is not checking whether this particular token is allowed to access G user API or not in order to do that we need to actually add a scope related check so if you look at this token there is a attribute in the token called scope which says this token is allowed to call read user API we are not checking this right now in in this uh springboard configuration the only thing that is currently being validated is whether the token is valid or not it doesn't check whether the token has the permissions to call this API so in order to implement that if you go back to this documentation again and search for pre-authorize and here you can see you can add an annotation in Spring called pre-authorize and specify which scope is required to call that particular API so but before even doing that you need to enable the method LEL Security checks in your springbot application so in order to do that here in the documentation somewhere in the documentation so if you open this o to client or maybe o to login no sorry I think authorization yeah in authorization select method security you need to add this annotation in your springbot app so copy this annotation go back to your application add it and make sure you import it so the class got imported here save it now go back to your controller and again go back to your previous page and add this pre-authorized again make sure you import it and in our case the scope is actually this one SB user API slre user now stop it run it and let's see what happens it it will still work but I I will show you like what happens if it doesn't work so I'm still getting the user details because the token that I I'm passing has this particular scope now let's do one more thing let's make it more interesting so let's actually create an new API called Write user and I'm going to just return this message called writing user details and copy these two things generally right user is a post mapping so let's actually make it a post mapping import it and let's call it update user and let's actually change the scope to update user okay so now let's restart the application and see what happens so so let me again call the same get user API I am getting the response let's right click duplicate this request change it to post update user so I duplicated the request so it use that same authorization eror and let's try calling that API again see what I'm getting now 403 forbid done so if you look at this diagram again this is the PC scenario so basically what happens here is if I call get user oh sorry if I call get user I'm getting the user details using that same access token but if I try to call right user I'm getting a 403 Forbidden error using that same access token the reason is because the access token that I am passing doesn't have the scope which is update user and that is the reason why you are seeing a 403 Forbidden error if the token itself is invalid you will see a 401 error but in this case the token is valid but it doesn't have enough permissions to call that right user API that's why you are seeing a 403 Forbidden error now let's quickly go ahead and add a new scope update user details and let's actually add the scope here so I added both these Scopes to this user client this app client and let's get a totally new token access token here and let's check this access tokens Scopes in jw. I now I have both the Scopes and let's see what happens now when I call get user I still get the user details now when I call update user it should work yes now update user also works that is because the new token that I generated has both the scores and it has permissions to call both the apis so this is how you do the end to end configuration on to secure a API that is exposed by a spring boot app using AWS Cognito or two Scopes so I there are lots of steps involved so if you face any issues please feel free to add a comment in the YouTube video and I will I will respond to you I hope you enjoyed this video again please don't forget to subscribe to my channel thank you
Info
Channel: Security in Action 101
Views: 4,797
Rating: undefined out of 5
Keywords: sso, singlesign-on, aws, iam, identityaccessmanagement, identity, access management, identity provider, aws knowledge center videos, security, oidc, idtoken, java, spring, springsecurity, springboot, javaawscognito, springbootawscognito, springbootsecurity
Id: 7zyhENQRb7c
Channel Id: undefined
Length: 31min 25sec (1885 seconds)
Published: Sun Dec 03 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.