How to integrate AzureAD B2C with AWS API Gateway JWT Authorizer?

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 get an access token from Azure ready b2c using oauth to client credentials Grant and then secure the apis that are hosted in AWS API Gateway using the access tokens that are generated from azure adb2c before going into the configuration steps I will quickly explain the end-to-end flow using this diagram so let's say there is a client application which wants to access apis that are hosted in the AWS API Gateway in order to access the AWS apis sorry the apis that are hostel in the AWS API Gateway it needs some kind of a token so like for example if it is a public API then it's fine like uh if does if it doesn't contain any sensitive details you can just host it in API Gateway and open it for public but if it is a critical API or a API that returns sensitive data you need to add some kind of a security layer and API Gateway actually provides an out of the box JWT authorizer which you can use to secure the apis and this JWT authorizer can accept jwd tokens from any identity provider like azure adb2c and so if you look at this diagram the client application will first get a access token from Azure adb2c using oauth2 client credentials Grant and that's what happens in the step one and step two and once it gets that JWT access token from Azure adb2c it can then pass that access token in the header to to the apis that are hosted in AWS API Gateway and what AWS APA Gateway will do is it will use the JWT authorizer to validate those access tokens by getting the public key from the Azure ID b2cs jwks URI and then validate the signature of the token if the signature is valid it will also valid validate the claims within the token like the audience claim the Scopes claim and if everything is fine then it will call the back end API which is uh which sits behind the AWS API Gateway to get the data and return the data back to the client but any if any of these validations fail then it will either return an unauthorized error if the token is invalid or a forbidden error if the token is valid but the Scopes in the token doesn't allow to access that API so I will I will show all these things in the demo but at a high level what happens is a client application will get an access token from Azure ID b2c and then pass the access token to the AWS API Gateway which in turn will validate the tokens using the JWT authorizer and then either allow access and written data or deny access to that client application so you can actually download this diagram from my GitHub link it's I use the draw.io website for drawing this diagram it's a open source and you can download this file and open it in the draw.io or you can check in into your GitHub and directly open it open from GitHub in draw.io I will share these links in the comment section so let's now go to the configuration steps so we need to do some configuration on the Azure ID b2c side as well as on the AWS API Gateway site and then we can use Postman to test this flow so let's first start with Azure ad p2c so we need to configure a oauth to client credentials app in Azure ID b2c so go to Google and you can search for Azure adp2c client credentials and you will find this link which explains the step-by-step instructions on how to configure an application in Azure ID b2c and get the tokens using client credentials Grant so I will quickly go through these steps you can go through this document at a later point of time anyway I will also refer these documents when I'm doing this setup so first we need to register a web API app so what it means is basically you need to create an application in Azure db2c which represents the API so let's actually start with that I will create a new app called let's name it as user API app let's just name it as user API register the app and the next step as per the documentation is we need to actually set these Scopes the application Scopes so let's actually do that go back to this configuration go to the app roles and let's create two different app roles I will name it as read user and select the applications here and name it as read colon user read users and I will create one more called read posts maybe it's just dummy apis which I'm using for testing so let's you can configure these Scopes according to your application requirements so read colon posts and read user posts so I created two application roles here and the next step that we need to do as per the documentation is set an application ID URI so in order to do that go back to that same application registration and then go to expose an API and then click add so here let's replace this API colon slash slash with let's go to the settings and copy this one which is our domain and again click this add remove this API colon slash slash and let's add this one and slash that value so please make sure you configure this type of a URL otherwise you might face issues when you are trying to get the token so now click save and you can again see these details in the documentation as well but they have given an example of how to configure an application ID URI so here in the documentation they talk about adding these app roles to the map through the Manifest file but I did it through the UI and if you go to the Manifest file you can actually see the app roles that I defined using the UI pages but you can manually modify this file as well in order to add these application roles so we are done with the API application registration now we need to register the client application so let's again go back to Azure ready app registrations so we have the API app now let's actually register a API Gateway Client app let's call it as a AWS EP Gateway Client app so if you look at these instructions it says you need to actually set this particular manifest value to the to the number two so let's go back here go to the Manifest file and if you search for that it's here change it to 2 and click save and once that is done you need to actually create a client secret which we can go which we can do later let's actually first grant this application access to the apis that we created in the previous step so in order to do that let's actually go back to the screen and then go to the API permissions and let's add a permission go to my apis and this is the API that we defined which is user API click that one select both the Scopes and add permission and here it gives that it's not granted default access so let's actually provide default admin consent for both these scopes so now the default admin consent is given for both these scopes so now this client app so what I have done is basically defined an API application in Azure adb2c under client application in Azure ID b2c and give permissions for that client application to access that API application so these are all now just configurations we will see these things live in action when we actually configure the API app in the AWS API Gateway so what we have done right now is just the security related configuration in azure adb2c so in order to get the access token you can see these instructions again here so you need to build this URL which is this tenant name all those things and then pass all these values in the post request body so let's actually do that and see if we are able to get an access token and I am using Postman for getting the access token so I already have a blank request here change it to post paste it here and we need to replace this tenant name so let's go back to this Aussie already b2c screen go to settings and we can see the tenant name as second action 101 gmail which is my Gmail ID and you can leave this on microsoft.com because it's already present here so don't copy that one just copy that first text place it here and then copy it here as well and then it asks for a policy so let's go back to this uh Azure ID b2c and scroll down and you will see actually you will see a place where you can see the policies I think this one user flows yes so if you go to this user flows you can see this policy and you can just copy that and paste it here the next thing that we need to do is you need to pass these request body parameters so let's actually go here go to body change it to X form URL encoder and copy this paste it here and this is a constant value because we are going to get access token using oauth to client credentials Grant so the grant type needs to be client credentials then we need to pass declines client ID I will come back to that value and client secret let's just paste the key names here and then update the values and the scope so the first thing is client ID so in order to get this client ID go to that uh app registrations again and if you remember we created a AWS API Gateway Client app so go to that app copy this application client ID paste it here then we need a client secret for this client ID so let's again go back to the same app and go to the certificates and secrets let's generate a new client secret let's name it as version one copy this value paste it here then we need to define the scope and then go back to Azure ID screen and if you look at this scope this is the format of the scope so in our case if you remember for the API application that we configured in Azure ID p we actually configured an application ID URI so let's go back to that Azure ID configuration app registrations user API this is the one I configure go to expose an API copy this value paste it here and then if you look at this documentation it asks us to append slash dot default so append that value and let's try eating this URL yes so looks like all the configurations were fine and that is the reason why we are getting this access token otherwise you will get some error and then you need to again debug so let's view this access token in JWT dot IO website and see what are the contents of this access token so if you look at the key at Key claims in this access token it is the scope claim where we can see read colon user read colon posts these are the API Scopes which I defined for that user API app and then in the client application that I created I actually authorized that client tab to allow that to access these API scores so that's why when I'm getting an access token for that client app I am getting both these codes then you can see the audience value which is actually a representation of that client application resource so this is the audience value so if you go to this user API configuration and if you look at the client ID it starts with d8 ends with 83. and here you can see this starts with d8 and it's ends with 83. so what this actually means is the audience of this access token is the user API application which will be hosted in AWS API Gateway and which we will see at a later point of time so this audience value represents the user API application and this scope represents the API which this client application can access basically it can read a user it can read the posts of the user and then the issuer represents the Azure ready b2c tenant which is my tenant like if I go back to this Azure ID b2c and if I go to the overview somewhere somewhere I should be able to see all the tenant details it's not showing up here let's see here or let's actually go to one of the user apis so if you look at this directory tenant ID it starts with c174 I think it should match with this one somewhere yes so it starts with C1 and 74. so this is my Azure ad b2c tenant ID in your case it will be a different one because it is unique across Azure reading across all customers so these are the main claims like the scope the audience and the issuer so now we are done with the Azure ready p2c configuration for the client credentials so what what we have done until now from this diagram is Step number one and step number two so now we need to go ahead and configure the AWS API Gateway application and after that we should be able to test these steps three four five one six so now let's go to the AWS Management console go to the API Gateway service and let's actually create a HTTP API so please note that the JWT authorizer is supported only with HTTP API option and not with rest API option if you are using a rest API with Azure ID b2c token you need to build a custom authorizer a Lambda authorizer which can receive the token validate the token and then allow or deny access so if you want to use the out of the box JWT authorizer then you need to select HTTP API option so let's now build a HTTP API let's name it as user API the same thing that we named here in Azure ready b2c so let's name it as user API click next let's configure The Roots later so click next let's leave these things as is go to next and create now let's create a couple of end points like for example let's name it as get user and one more called get posts so for the get user let's actually attach an integration what it means by an integration is basically like the APA Gateway endpoint that I created the root route that I created it just says slash user so when I hit the slash user endpoint I need to get some data right so APA Gateway needs to contact some other application in the backend to get that data and it can be anything like if you look at this option it can be a Lambda function it can it can be another HTTP URI from where APA Gateway will get the data and then return it back to the client or it can be a even Bridge it can be multiple things like you can scroll down and see so in my case I'm just going to use a dummy Json data that is available in Internet so just search for Json test data and I'm going to use this Json placeholder fake rest API okay this will just return some fake data just for testing purpose but in your case if you are building a real application you might have a Lambda function which is querying some database getting the data and returning it back to the client or you you can have some other integration like whatever I showed here right it can be a step function or a simple queue service or a private resource it can be anything so this is just for demo purpose I am using a publicly available test data so if you see this value it's actually it will return a Json data so I am going to add a HTTP URI HTTP method can be any just paste that your URL and click create and similarly I'm going to create and attach an integration for slash posts same HTTP URI if you go back here and you have a posts your dummy data just add that one create and it should have already got deployed by because my D Stage is default it should have got deployed by default let's actually test that so if I go to this API I have this URL which AWS API Gateway created by default for this particular uh HTTP API application so let's copy that go to postman and type slash user so why I am typing slash user is because I created a route called slash user just click Send yes I got that same data which we saw in that fake data website now if I type posts I got the posts so now if you look at this API both these API slash user slash posts there is no authorization for these two apis so anyone from internet can access these apis and get the data now if we want to add a security layer on top of that we need to attach an authorizer to both these endpoints and let's see how to do that so now as I mentioned both these apis are open to public now we are going to add an authorization layer on top of these two endpoints and we are going to authorize both these apis using the access token that is generated using Azure ID b2c client credentials Grant so let's first start with the user and attach an authorization and let's create a new authorizer and here you select JWT authorizer let's name it as Azure ID b2c JWT authorizer and it asks for the issuer URL so if you remember this decoder token from JWT dot IO this is the Azure adp2c token you can see this ISS claim just copy that value and come back to this screen and paste it here and then it asks for an audience value again go to this same jwt.io copy this value and paste it here now create and attach so now if you see both these routes slash user slash post now we have added an authorization layer for the get user API but the get posts is still open to public right so let's actually check that now if I try to hit get user I am getting an unauthorized error because now this API is secured using the Azure ID b2c access token until and unless I pass a valid access token from Azure ADP to see I won't be able to access this particular API now if I try to access posts I got the response because it is still open to public so now let's first try to get a token from azure adb2c and then access this slash user API but before that we need to do one more configuration so if you if you see this configuration I added a JWT authorizer to this user route now let's edit this authorizer sorry not edit the authorizer so let's add an authorization scope so let's actually say that only users only client applications which has this read colon user scope can access this API so let's add the scope as read colon user and click save so now if you look at this diagram like whatever I mentioned here what the JWT authorizer will do is it will validate the access token signature using the public key downloaded from jwks URI and then it will validate the audience and also the Scopes so let's actually try to get a new token from azure adb2c so we got a new token and you can again check this token details here you can see the token details here it has both these Scopes read colon user read colon posts now let's actually pass this token to the re to the slash user API in authorization header so I'm just going to pass the token I should get the access let's see I don't know what is happening let's see maybe there is something wrong in the configuration let me check it so yeah everything looks fine there is something wrong in the configuration or maybe it's taking some time oh okay okay let me check let me just so the audience looks fine the issuer URL looks fine yeah everything looks good and this one is read colon user let me actually confirm that read colon user should ideally work let's see what is happening oh sorry sorry yeah it was my mistake I should have added it as an authorization header but instead I added it as a query param that's the problem yep let me again copy that token from here paste it here yep I got the response now it was my mistake I added it as a param which is actually a query param instead of headers so you need to pass the authorization header with the taxes token and now I got the response now let's do the same thing for the post API so I will attach an authorizer for the Post API so if you see this drop down I already have this Azure ready p2c JWT authorizer let's use the same thing and for the post if you remember we defined a specific scope for post so let's actually copy that read colon posts and edit your save it here now if I try to access the posts API it should give me an authorization error so let's see that yes I got unauthorized error because now the post API is also secured using Azure adb2c access token so now let's actually add use the same access token which we use for the flash user because that same access token has both these Scopes read colon user and read colon posts and let's add it here yes so we got the response so if you look at this diagram now we have configured the steps three to six and now we are able to get the data and we have secured both these apis using AWS API gateways out of the box jwd authorizer so now let's test this forbidden option like like unauthorized depends when the token is invalid but forbidden error is written when a scope is not present in the access token that is I pass a valid access token but this scope is not available so let's say I am trying to read the posts but I don't have the read colon post scope in the access token the access token is still valid but the scope is not present so API Gateway will return and forbid an error and not an unauthorized error in order to test that let's again go back to the app registrations in azure adb2c go to the AWS API Gateway Client app API permissions and let's actually revoke admin consent for read colon posts so now what will happen is if you look at this access token I see both these Scopes read colon user read colon posts now that I revoke the admin concern for read colon posts when I try to get a new access token from Azure ready b2c the JWT should not contain that read colon posts scope let's actually check that I think it will take some time let's actually wait because sometimes even if I change right it takes a minute or to get refreshed so let's again get a new token and see what happens let's see if something changes yes so now if you look at the scope I have only read colon user but I don't ever read colon posts so if I try to access read colon user now I should still get a response because this access token has that scope so I'm still getting response for the slash user API but if I try to access the posts API I should get a forbidden error yes so if you look at the response it's four zero three forbidden so that is because the scope validation failed that is the token is valid but this client application don't have permissions to read users posts it has permissions to read only user details so this is how this security layer works in the API Gateway along with this JWT authorizer and if you are building your own API application where you are using a combination of azure ID b2c and AWS API Gateway for hosting your apis this is how you can control the access and add a security layer and uh this involves again multiple steps as you saw like configuring Azure adb2c AWS APA Gateway and there are lots of things which can go wrong like like I made a mistake in a test but there are lots of things that can go wrong in the configuration steps you can always come back and refer the videos again to check which Step got missed out or where you made a mistake but if you still can figure out feel free to post your questions in the comments and I will be happy to respond and I've as I said in the beginning this diagram is available in my GitHub public repo I will share the report details in the comments and you can download this draw dot IO file and you can actually open it in draw.io like you can save it in your local and then open that file from draw.io like I have already integrated my draw.io with my GitHub so I can directly open it so if you already have a GitHub you can download this file from my GitHub repo upload it to your GitHub repo and directly open it from draw.io or save it in your local and open it in draw.io whichever whichever is easier for you so this is the end-to-end configuration I hope you like this video again Please Subscribe if you like this video and share this video with others thanks for watching thank you
Info
Channel: Security in Action 101
Views: 2,692
Rating: undefined out of 5
Keywords: aws, oauth2, clientcredentials, iam, identityaccessmanagement, identity, access management, apigateway, awsapigateway, awsapigateway auth0, awsapigateway jwt, jwt, azuread, azureactivedirectory, azureadb2c, azureadawsapigateway, azureawsintegration, azureadaws, microsoft, azure
Id: 3iJ-qVfZwQo
Channel Id: undefined
Length: 34min 38sec (2078 seconds)
Published: Mon Jun 26 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.