We are using Azure AD B2C custom policies with a call to a REST API as part of one of our technical profiles validation. It works fine when response times are short enough. However, if we are adding business logic inside our REST API (adding a user to database and other steps), the method call could be taking more than 20s (for instance when the server is not warmed up).
In this case, it seems that Azure AD B2C is retrying the call to the API multiple times which does not work for us...
Would it be possible to change this behavior ? (for instance in the custom policy itself or in the REST API code)
No, there is not currently a setting to override this and I have not heard of any plans to introduce one. I recommend you use some sort of middleware such as an Azure Service Bus to receive a message once the user logs in, then later process your business logic on a schedule or in the background.
Related
I am creating a React SPA that will connect to a dotnet Web API backend. I want to use b2c to handle auth.
I want to have endpoints in the API protected based off the claims in the b2c token, also want to check claims in the frontend aswell.
Following along with token enrichment docs - https://learn.microsoft.com/en-us/azure/active-directory-b2c/add-api-connector-token-enrichment?pivots=b2c-user-flow
I can use an API connector to enrich the token with additional claims before it is sent back to the client, presumably with a function to provide values from my database in a users table.
If my database will also be hosted in azure, how would I develop and test this locally?
Is this flow the best way to achieve the desired behaviour? If not what are alternatives?
I've done two methods when testing 'locally'.
Create an Azure Function echo API service in 'cold' mode to reduce cost. This will allow you to easily ping it and it will ping you back the content. You can also add test cases pretty easily. This isn't really 'local' but, it's low cost and allows you to collaborate with multiple team members.
Use a free web service like Post Test Server. With a couple clicks you are off and testing with lower effort. The problem with this solution is it is public so do not use any proprietary or confidential information. I've created very complex dot notation in body of REST-API technical profile via custom policies and this was effective testing data formatting and internal business logic.
Last option could be creating a web service locally on your device - I haven't done this end-to-end but you would follow this same process as hosting an application locally with localhost.
You can deploy an Azure database solely for development purposes. Or you can just mock the API response so that you can do some basic e2e testing: SPA -> B2C -> API.
I have a .Net 5 Web API hosted on Azure App Service.
The API has three Background services running as hosted services, which perform long running processes such as bulk emailing and SMSing, as well as other functionality that runs once a day on a timer.
I am thinking about moving out these hosted/background services into separate Azure Functions, which I would then call / trigger from my API via an HTTP request (except for the one that runs on a timer)
My concern is regarding authentication. How does that work with Azure Functions? Currently, my Web API is using Auth0 as the authentication server. So, when the user uses the front-end web app (Angular), he logs in (via Auth0's login form) and then the front-end retrieves an access/bearer token from AUth0, which it then includes in every call to the API (in an Authentication header).
Now, obviously I don't want just anyone to be able to call the Azure Functions - only my Web API should be able to do so. But how does that work? Does the API need to forward the access token it received from the front end to the Azure Function when calling it? Or is there something I need to set up in Azure Portal to tell it that my API must be allowed access to the Azure Function (and block any requests from any other origin)?
I've never used Azure Functions or even WebJobs before, so I'm a bit lost.
Thanks
When creating an HTTP-triggered Azure Function, by default it is set to have authorization level = Function, which means that any app trying to invoke that function via its URL needs to know the specific access key that is generated for that function upon creation.
In your example, your web API would store that function's invocation URL and access key in its configuration, and invoke your function with that key. Since the key remains entirely server-side on Azure, nothing else can access it, so it's completely secure.
Depending on your requirements, you can then also layer other types of authorization/authentication (e.g. bearer token) on top of the access key mechanism, or use those instead of access keys (by setting the function to allow anonymous access).
For maximum security, I would recommend using both the function access key as a first step to ensure that nobody except your apps can successfully invoke the function, and then passing along and authenticating the bearer token to ensure that the app trying to invoke that function is indeed permitted to do so.
Just be aware that Azure Functions is a slightly different beast to standard ASP.NET Core, particularly in regards to middleware which it doesn't really support yet, so you'll likely need to roll your own code for reading the bearer token from the incoming HTTP request's headers, and verifying that it's valid.
Reference: https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-http-webhook-trigger?tabs=csharp#authorization-keys
For this requirement, you just need to enable "Authentication/Authorization" of your function app.
Follow the steps in the screenshot above and when you click the forth red box, choose "Express" tab and click "ok" at the bottom of the page without do anything. It will create an application in your Azure AD which has same name with your function app.
After that, when you request the function app url in browser, it will ask you to login.
For more details of the steps, you can refer to this document.
Hury's guidance is best - you want to avoid using API keys on your production functions and use this just for testing. Official guidance is here:
https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-http-webhook-trigger?tabs=in-process%2Cfunctionsv2&pivots=programming-language-csharp#secure-an-http-endpoint-in-production
Configure your Functions for AuthorizationLevel.Anonymous, and require Authentication on your Function as Hury describes. This will not only require end users to authenticate, but supports System Assigned Managed Identity when your function is called from other App Services. Less keys to vault or configure means less to steal.
Depends on what you mean by authentication.
If you just want to secure your functions you can use the authorization level = function.
However, if you need authentication with login, and you need to know the user making the request, you have to use bearer token with OpenIDConnect server.
Always use stateless authentication regardless your method.
We have few micro-services that are used by a UI. Azure B2C is our auth provider. Each micro-service(API) requires an access token and needs to talk to a database for authorization. This database has role based access permission.
This is how it looks today:
With this we have two problems:
As Azure B2C do not allow adding scopes from multiple resources into one access token, we have to get multiple access tokens.
We are now at a stage where the UI need to call two or more APIs to display the data on one page.
We wanted to use GraphQL as an API Gateway. Something like this:
All the micro-services are placed inside a private vnet and only GraphQL API is allowed to talk to them. GraphQL Layer handles all authentication and authorization.
Now the questions are:
Do you see any problems with this approach?
Is it okay to use a client and secret for communication between GraphQL layer and other API's? or Is there an provision in Azure B2C that can do this validation with out GraphQL layer requesting individual access tokens?
what are the additional advantages of adding Azure API Management to this (other than logging, analytics, rate limiting etc)? Do I need to worry about SSL termination?
Option 2 looks like a good architecture.
A common pattern is for the UI to call a dedicated 'entry point' API, which then orchestrates calls to microservices in a private network - as in your second diagram.
Eg an Online Sales UI calls only an Online Sales API
This also helps to keep UI specific requirements out of microservices and keep responsibilities clean.
In OAuth terms as you say there will be a single resource - the entry point API - and you should only need a single access token.
The entry point API's token (or its claims) can then be forwarded directly to Microservices and used to identify the user there if needed.
I'd avoid getting additional tokens for microservices and just enforce authorization based on roles from your user database.
In some cases it may also make sense to also enforce rules such as 'Online Sales API not allowed to call Payroll microservice'.
Personally I would develop entry point APIs using the same technology as microservices.
I have configured Azure Application Insight for monitoring our systems and was trying to enable the alerting. I'm using app insight availability test which provides a functionality to call a webhook URL.
I wrote a webhook using HTTP triggered Azure function, but the problem is it exposes a public URL which if called will raise an alarm on our internal alerting system. So I plan to authenticate the call to webhook.
Is there any way I can authenticate the call possibly using OAUTH.I don't want to provide the token in URL, looking for something secure. Another problem with manually using token in URL is that token rotation will require manual work.
Any suggestions on I can automate this task which will take care of secret rotation will be appreciated.
I believe token based authentication is the only possible route as of today as documented here.
But I think you should still be able to use a Function App without worrying about key rotation since the function keys can be read through the Functions API if the AzureWebJobsSecretStorageType app setting is set to files as documented here.
We have a multi-instance Saas Application:
Each of our clients is given their own instance and their own subdomain for the site.
Our application (Web app & API) is protected by Azure, currently with the ADAL javascript libraries
We also have a second API for system-level integration that needs to be protected, currently using a second 'native' azure app, but this is likely incorrect and we want to consolidate
Our application reads and writes to the Azure AD both through the AzureAD Graph API and Microsoft Graph API (including password reset calls)
We're looking at Azure AD application configuration options and want to make sure we're building the most sensible and secure Azure AD Application. Here are some of the documentation we've been looking at:
https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-integrating-applications
https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-protocols-oauth-client-creds
https://learn.microsoft.com/en-us/azure/architecture/multitenant-identity/
https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-compare
We want the application to be multi-tenant to ease configuration, and allow availability in the Gallery; but when looking into doing so we're left with some security questions.
A. Which application version to use
1) v1. Allows access to both Graph API. And as suggested by Microsoft we should use this when we're not concerned with Microsoft Accounts.
2) v2. When looking at the MS Graph API documentation it recommends using v2. Reportedly doesn't work for AzureAD Graph API? Allows the same app to be of multiple types (Web App/API and native), which we may or may not need to protect both our web api and our system api (which we're still trying to model).
B. How to manage the reply URL when our clients have different sub-domains?
I've noted the following options:
1) On the app registry, we add the reply urls for all of our customers. This seems okay because we only need to do it once, but feels odd. Is there a limit to the number of reply urls?
2) Have one reply url, but manage an external tool to route the responses to the correct instance, leveraging the state url parameter. Microsoft seems to be suggesting that in this link: https://learn.microsoft.com/en-us/azure/architecture/multitenant-identity/authenticate I'm not sure if ADAL allows us to set the state for a return subdomain url though. Is this approach common?
3) Is it possible for each ServiceProvider instance in our client's directories to configure the reply url to their own subdomain? I feel like this would be the cleanest approach, but I don't see documentation for it. It would be nice if we could set the replyURL programmatically as well.
C. How to manage authorization to the Graph APIs (AzureAD and Microsoft Graph)
I've noted the following options:
1) Use the client credential flow, with a single application key (used for all clients). As clients subscribe they will admin consent with our app to give the application permission to their directory. Of course we'd do our best to keep that key secure. But if for some reason it was compromised this would put all of our clients at risk, not just the one instance that was compromised.
2) Same as 1, but use a certificate instead of a secret key. I understand this could be a little more secure, but I don't see how it wouldn't suffer from the same issue as 1.
3) Instead of using application permissions, use delegated permissions with an admin user. This would be good, in that it inherently prevents one instance of our app from talking to the wrong directory. However changes to the administrator may interrupt service; and I think it is best audit-wise that our application is responsible for the changes it makes. (Also, do delegated permissions allow for password resetting? I know for app permissions you need to run powershell script to upgrade the application's directory role)
4) Is there some way for the service principal to generate a unique key for it's directory on creation? can this be handed back to our app programmatically? Perhaps during admin consent?
Really good questions. I'll try to answer each to the best of my knowledge, but if someone has other ideas, feel free to comment/add your own answer.
A. Which application version to use
v2 should allow you to call Azure AD Graph API. The documentation you linked shows an example of specifying Azure AD Graph scopes:
GET https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=2d4d11a2-f814-46a7-890a-274a72a7309e&scope=https%3A%2F%2Fgraph.windows.net%2Fdirectory.read%20https%3A%2F2Fgraph.windows.net%2Fdirectory.write
The main decision point if you should use v2 is: Do you need to support Microsoft accounts which are not in an Azure AD? If yes, you need to use v2. Otherwise there is no problem using v1 (well, lack of dynamic permissions).
Since you are using Azure AD Graph to modify things, I'm going to guess pure Microsoft accounts will not work for you. I would recommend sticking with v1.
v2 also has some limits: https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-limitations
B. How to manage the reply URL when our clients have different sub-domains?
I could not find documentation on a limit for URLs. It could be that you can add however many you want. But I am not sure :)
If your subdomains look like this: https://customer.product.com, you can configure the reply URL as:
https://*.product.com
It will then allow any subdomain to be specified in the redirect_uri.
Though note that at the time of writing this, wildcard reply URLs are not supported in v2.
C. How to manage authorization to the Graph APIs (AzureAD and Microsoft Graph)
Using multiple keys makes no sense as they are all equal anyway :) Any of them could be used to call another tenant.
You can store the secret/certificate in an Azure Key Vault, and then use Azure AD Managed Service Identity to get it on app startup.
I would prefer using delegated permissions, but if the users of the app won't have the rights to do the things your app needs to do then that does not work.
I would just make sure it is not possible for a customer's instance to call to the APIs with another tenant id. And also make sure token caches are separated in such a way that it is not possible to get another tenant's access token (an in-memory cache on the instance would be good).