How do we run automated testing when using OAuth2 and Azure AD - azure

Our scenario is that we have an API which is currently only secured by a subscription key in APIM.
We plan to change this to also secure it with OAuth 2 following this guidance from Microsoft, we will then use the JWT validation policies within APIM to ensure that the user requesting access is a member of the appropriate groups to access given endpoints etc.
However as part of our release process we need to run some automated tests which call the API and check that certain data is returned.
Because these tests are run as part of an automated release pipeline we are struggling to understand how OAuth will fit into this process - as a user is required to enter credentials for a token to be issued...
We originally thought that we could just request a token manually once and then hard code it into the tests, but as tokens are only valid for a short time this isn't a good solution.
Other things we are considering are :
Creating a "test user" in AD and storing their credentials in the test project and then when the tests run we can request a token using the "Password" grant type and passing the username and password" however this doesn't seem like the best from a security point of view, even though the user would only have access to a very limited subset of the APIs functionality it still doesn't seem like a good practice.
Requesting a token using the client secret, however the downside to that is this is that the JWT does not contain the groups claim so this token will not pass JWT Validation.
This must be something that others have encountered? What is best practice in this scenario?

As you can see in the article you reference, you will be using Azure API Management to be the entry point to access your API. So, using the API Management you will have subscriptions with keys for your API. You just need to create a subscription for your automated testing, and save the key in the Azure Key Vault. And then during the deployment, you pull your subscription key from your Key Vault, and use it to call the API Management Endpoint, that consequently will call your API.

The solution that we went with in the end was to create a new App Registration for the Test project, then in APIM we added a rule so that the JWT policy is not applied to connections from that app.
Might not be the best solution but it works.

Related

Azure Active Directory add custom data to Oauth2 token

I'm using the auth endpoint https://login.microsoftonline.com/tenant-id/oauth2/v2.0/token programmatically (Nodejs) for getting back a token that will be used against my API. I have everything properly configured to send the request using a "Client secret" I setup on the Azure Portal - App registration service.
This issues a valid token that I can later check with the help of the Passport azure AD npm library. However I've been looking for a way of somehow adding more metadata to that token (i.e. a custom user name) so that when it gets validated and parsed by my server upon future requests I can extract this information.
When issuing tokens using a frontend application library (like msal) I have access to some of the user's information on the token (like its oid and email address). I'd like to be able to "extend" the token generated by the client secret to also contain a couple custom fields, which I can use after validating and parsing it.
Hopefully that's clear enough. I'm lost on how to achieve this. Thanks
It is a common requirement for APIs to authorize based on claims stored in the business data, eg roles or other custom data.
OPTION 1
Ideally the authorization server can reach out at the time of token issuance to an API or database to include the custom claims. This is not always supported though.
OPTION 2
Another option is for the API to process the incoming access token into a ClaimsPrincipal and to include custom values at that point. For an example see this code of mine.
PRIVACY
When adding more claims, you should also be careful about revealing sensitive data in JWTs returned to internet clients. Eg if you include names and emails, they are easily readable, and this can sometimes be a security concern.

Where is JWT Validation Supposed to happen in APIM+AZ Function stacks?

I'm unclear on whether I've missed something with the way API Management Gateway/Azure Function communications work. Initial requests are supposed to contain a JWT which contains server-signed assertions related to user roles.
Within APIM/Azure Functions, there is the concept of a 'shared secret' used to authenticate B2B communications. Which means that some level of trust occurs between the two systems.
Obviously, I could implement JWT validation in both places, but I cannot find any documentation from Microsoft or similar that says 'here's how you're supposed to do it.'.
• There is no official documentation from Microsoft regarding JWT validation in APIM as most of the documentation is related to the policies regarding the usage of authentication, access restriction, caching, cross-domain, distributed application runtime, integration, transformation, etc. in APIM. But you surely can refer to the link below which is no less than a documentation that explains elaborately how the policies in APIM can be used to achieve the results for various operations defined in the workspace.
https://azure.github.io/apim-lab/apim-lab/7-security/apimanagement-7-1-JWT-Validation.html
• According to the above link, JWT validation happens at the Azure B2B end as the token issued to the app service is validated against the configured authorization and access policies defined while granting access to perform the required operations for the app service. For your confirmation purpose, you can add a validate the JWT policy for the concerned app service in your APIM as given in the below link to confirm the source where the JWT validation happens. For that purpose, you will need an orchestration app like ‘Postman’ and create a corresponding app registration in Azure AD for the correct validation results: -
https://carldesouza.com/adding-a-validate-jwt-policy-to-azure-api-management/
In the above links, you will get an overall understanding of the various parameters which are included and need to validate in the payload, header, and signature section to ensure that the JWT is a genuine one.

AzureAD: Using long-lived refresh tokens for external API "system" consumers?

I'm developing a bunch of APIs that will have both internal and external (to the company) consumers. I'm using AzureAD for authentication. Whilst these consumers will be integrations written in code, I don't want to have to create and manage dedicated "app registrations" for each client/consumer. I also want to be able to use roles for more granular permissions.
It feels like a long-lived refresh token is the best option for this, and I've written a working proof-of-concept for this, which meets the requirements perfectly.
Given this is security though - I wanted to ask if I'm doing anything stupid or wrong.
First question - is it okay to treat a refresh token as a long-lived secret that consumers can store in their secure config, then their systems programmatically use that to query an access token to use against our APIs?
If this is okay - my second question is regarding the client id and secret. Because the implicit flow doesn't support refresh tokens, I'm using the authorisation code-flow. For this, it looks like I have to pass the client-id and client-secret as well as the authorisation code or refresh token to AzureAD. This means that I need to create a dedicated "auth api" that the consumers call to request these tokens. This auth api literally just then makes a downstream call to AzureAD passing the clientid and secret (which the consumer obviously doesn't know about). It feels like if the implicit flow supported refresh tokens I wouldn't have to implement this "auth API" at all. But because I have to use the authorisation code flow - it's forcing me to implement a proxy "auth api" for all token requests to go through. Am I missing something - or is this the way I should be doing it? It's fine if so - as this is what my PoC is doing, and it's working. But again, just wanted a sanity check on this with it being security related.
Ps. I know Azure API Management gives a lot of this functionality - but for reasons out of scope of this question, this isn't a good fit for us.
Update
To add another couple of reasons why this method fits my use-case really well...
A lot of internal developers will also be using these APIs (internal to the company). They already have AzureAd accounts anyway. So this then becomes super-simple to manage - we just have a bunch of security groups with certain roles in the app registration, and we can just add devs to those groups. And they don't need to know the client id / secret - they just use their own user account.
The APIs have Swagger UIs. Using users instead of clientid/secret - means developers can use the Swagger UIs with single sign on.
WEB CLIENTS
So a web app is used by developers to sign in via their Azure AD account. Authorization Code Flow is fine, after which each user will get access tokens and refresh tokens for calling APIs. Tokens will include the user's role and APIs can use them for authorization.
EXTERNAL API CLIENTS
These might be B2B clients and therefore use the Client Credentials Flow. Tokens issued to these clients would then have no user context.
INTERNAL API CLIENTS
It is a little unusual for a developer to login to a web client and then take tokens issued and use them in other apps. This is partly about reliability and partly because different apps generally access different areas of data. See this scopes article for details on designing how components call each other.
REFRESH TOKENS
A refresh token is something that will expire so you need a plan for this. Avoid using them in static configuration. Consumers need to handle refresh token expiry in order for their app to be reliable.
CODED INTEGRATIONS
Are these web clients or APIs, and how many distinct apps are there? It feels like combining these into one or a few client registrations is the right option. A common setup might work like this:
All developers might share the same registration
All web clients use the Authorization Code Flow - and you Auth API
API clients forward tokens to other APIs, to maintain user context

Azure Active Directory Token Validation

I'm integrating Azure Active Directory into a cloud platform. As our application is multi-tenant and relies on platform-specific claims, we've identified the simplest way to go about this is get an Azure AD token via our SPA, pass it back to our WebApi, validate it and return to the SPA a platform token with all the claims we need to go about our normal business (as if it was a simple username/password athentication request).
I'm concerned at the level of security for this though.
Some Context
As our platform is multi-tenant, we request that clients each register the application on their Azure AD portal, then supply us with the generated Application (client ID) and Directory (tenant) ID. We use these two pieces of information to make the initial request to Azure via our front-end SPA (following the node.js example provided by Microsoft's Quickstart guide when registering an app). Now because the user is unauthenticated at this point, we needed some way to return those two specific ids for the client. We have accomplished this using a sub-domain for identification.
E.g. acmeinc.mydomain.com will return a different Application (client ID) and Directory (tenant) ID than billy.mydomain.com. These are obviously public now as this request happens from an un-authenticated front-end route.
I can handle the token response just fine, both in the front-end and in the back-end when I pass it along, and validate that these two pieces of information are correct in the token, but seeing as the front-end is given them to begin with, validation on these is redundant. Also, validating the issuer seems equally redundant as someone who knows the Directory (tenant) ID, can fake that too (right?)
Am I missing something here? I would feel far more at ease if it were possible to request the client also include a claim that my platform generates privately such that I could validate this claim alongside the normal JWT validation. Custom claims do not seem possible from the Azure AD Portal.
Am I missing a critical step, or just overthinking this?
Someone cannot fake the issuer in the token because the token is digitally signed.
Without the private keys of Azure AD, it isn't feasible to generate a valid signature.
Without that, any modifications to the token will be immediately noticed because the signature does not match.
Your back-end should already be validating this signature if you are using standard JWT validation.
Requiring customers to register an app in their tenant is a bit of work that I would prefer not to put on them.
Have you considered making your app a multi-tenant app in Azure AD?
That way your customers could login to your app, consent to the permissions required, and start using it. Without needing to manually register anything.
This could be done in an on-boarding flow where the user signs in, and then they can decide what sub-domain they want.
You will at that point know their tenant id, which you can store. So in the future you can always use the correct tenant/directory id when signing them in.
The downside of this approach is managing the reply URLs.
With the specially registered apps, they can register their own sub-domain version as a reply URL.
With this generic multi-tenant app, you'll need to manage them.
And you can't add an infinite amount of them, and wildcards aren't supported anymore either.
So, your authentication would have to happen with a generic authentication reply URL like auth.mydomain.com, from which they would be redirected to their tenant URL.

User Authentication with IdentityServer and Azure API Management

I need some help with Azure API Management service.
At the moment we have a SinglePage App which is using two Backend Services (WebApi .Net Core) hosted on Azure. To Authenticate and Authrize user we are using IdentityServer (also hosted on Azure as a service) + SubscriptionService. Here IdSrv is authenticating the user and it also defines to which APIs the webapp has access. The SubscriptionService has information if the user has rights to given APIs. More or less like that.
So the flow is:
WebApp -> redirect to IdSrv endpoint -> login -> back to UI -> ask backend with user credentials (token)
Now, we want to add Azure API Management to the mix and I am struggling how to do that...
Initially we were thinking that we can hide everything including the IdentityServer behind API Management gateway, but looks like this doesn't make sense or is impossible. I found this as a helpfull reference: Generate Access Token and validate against IdentityServer4 through Azure API Management in which the second answer is quite important remark.
Based on that I think that I need to leave the Client to use IdentityServer to authenticate as this requires UI interaction but then somehow set a global policy in API Management to authorize the user using mentioned Send-Request policy. And then change backend to accept the JWT tokens from this policy? Is my thinking correct? How to implement that?
Or I should just pass the authorization-header from client request through API Management?
All those things are new for me so it could be that I missed something or messed up the terms...
The way you integrate APIM into picture may depend on goals you want to achieve with APIM. You could hide IdSrv behind APIM since there is Client credentials flow that would allow APIM to authenticate/authorize itself to an API, or you could have user authorize APIM once via Auth code grant and then store refresh tokens and use them to talk to an API. But I'm not sure that would be best since it quite a bit changes you system and forces you to solve other problems instead, like how to authenticate user to APIM. In some cases this may be a good approach, it's up to you to decide.
If you're fine with keeping IdSrv facing user, then we have APIM receiving a token with every request. You could then have a global/API policy in APIM that would send token received from user to SUbscriptionService to check user authorization to make a call) can do that with send-request policy), and either let the call pass or deny. This approach is most useful if you want to use different auth mechanism between APIM and backend, because if APIM is doing authorization work, your backend could avoid checking any user access, and instead just authorize APIM to do everything.
Check out this sample on how to authorize requests using external service: https://learn.microsoft.com/en-us/azure/api-management/policies/authorize-request-using-external-authorizer
it is quite late from asking this question but here I described how we have done that. We cover UI clients and Device clients with SSL Certification auth on APIM. In short words:
UI Client is being redirected to ID Server Loging page
APIM is doing Token validation with ID Server
APIM is doing SSL Certification verification in DB and returning back token like data for devices to pass some "device account" information.
More details can be found here:

Resources