Azure ADB2C access without a user - azure-ad-b2c

I am using an Azure ADB2C tenant to sign-up/in users with custom policies and rest api claims exchanges. This works fine.
Now I would like to start a service (daemon) that runs in a cloud environment for each user that signs-up with my service. This background service will access resources on other servers. Accessing these resources require a token and the service should only have access to the resources that the user has (i.e.: the access token used by the background service should also include the custom REST API claims). For the common users, this is taken care of by my REST API claims server, which enriches the token in such a way that it gives users' access only to the allowed resources.
I have found this page describing how to get access without a user. But this page assumes that the background service is a single instance that has access to all users' data that it needs. My background service is a 1-to-1 mapping to the signed up user.
Ideally this is how I see it working:
A new user signs up.
My REST API claims exchange gets called for this user.
Call Azure ADB2C to create a token for the background service. (Token should also contain my custom claims)
Start a new instance of the background service using the token created at step 3.
Return the custom claims for the new user.
This will happen for every new user, so every user in my system will have a corresponding background service running in the cloud.
Is this possible with Azure ADB2C? If yes, how?

The link you provide to get access without a user is only suitable for calling ms graph api and not for calling custom api.
If you are calling ms graph api, then you can indeed use the daemon-based client credential flow to obtain an access token (that is, without user involvement). This flow is usually used in Azure AD, but if it is used to call ms graph api, then it is also applicable to Azure AD B2C.
But if you are calling a custom api, then you must use a user login flow. Azure AD B2C obtains tokens in a different way from Azure AD. To use Azure AD B2C, you must first create a policy to enable users to sign up and sign in to your application.

Related

Pass AD user authentication to Azure REST API calls to provision resources

I'm creating a React App that requires authentication into Azure Ad. This is simple enough through the Adal libraries. When a user now requests my app, they are redirected to the login page first to authenticate.
The next step in my app, is for logged in users to be able to create various Azure resources, e.g. VM's through a simple form page in the app. For this, I'm looking at using the 'azure-sdk-for-node'. My problem, is that users can belong to different subscriptions based on their region globally. There are cases that users are in more then one subscription and have the rights to create resources in whichever subscription they are assigned to.
I'm not sure how to do this with the node SDK, as you only have three methods to authenticate calls:
Basic authentication (requires username/password which is redundant because they are already signed in
Interactive login (same as above)
Service Principal (everone uses the same 'account' to call the REST api's.
Not sure what's the best way then to do this?
https://github.com/Azure/azure-sdk-for-node

Microsoft Azure OAUTH2.0 - How can Multiple Source Clients call Azure OAUTH2.0 authentication

I create an Azure APIM instance, register it as an app in AD and then create a OAUTH2.0 server under APIM which is setup using the clientid/secret key of above registered app. I make a dummy API under this APIM and then protect it with this OAUTH2.0 server. I also add a JWT policy on my api to look for a token and authenticate against the tenant-id.(No claims mentioned).
Now lets say, i have a Customer (ABC) and for that i register another app in AD and create its Clientid/secret. Customer generates its token with the help of token endpoint (this endpoint is given under Endpoints tab of AD app registration option). Customer calls the API with this token and it works.
Issue: I didn't give any permission for my APIM App in AD to the Client App in AD but it still works, which essentially means that any Clientid/secret from any app registered in AD will go through my JWT policy of the API. Because it is just validating against the tenantid. How can we stop this and make sure that it works only for a customer to which permissions is given.
This is one of the major things I mentioned in my recent article: https://joonasw.net/view/azure-ad-authentication-aspnet-core-api-part-1.
Any app of type Web App/API in Azure AD can get a valid access token for any API in that Azure AD tenant.
Even before any permissions are given to it.
This is kind of a "feature" I guess.
Quote from the article:
If you only require an authenticated user, any confidential client in your Azure AD can acquire an access token for your API and call it. So it is important that you implement the user_impersonation scope check at minimum.
Now since your caller will call your API as itself, you need to implement an App Permission.
You can see how those are defined here: https://joonasw.net/view/defining-permissions-and-roles-in-aad.
Then implement a check that ensures the roles claim contains the value of the app permission you defined.
The claim will be a string array, so some kind of contains check needs to be made.
This will then require that this app permission is granted the caller before they can make the call successfully.
If you also want to allow delegated calls (i.e. calls on behalf of a user),
then add an optional requirement for the user_impersonation scope.
Those are stored in a single string claim (scp), space-separated.
So for that one you'll need a contains check on the string.

How to get Azure AD token in web app silently C#

i need to get Azure token in my app (C#) to perform Graph API operations on users, but without sign in all the time when app invoked (app must be full automate, working in timer job) so i have a question how to made process of token acquiring fully automate (without user)?
All that I found about this topic:
Get access without a user
But I failed to recreate it.
The OAuth2 flow you are describing is called the "Client Credentials Grant" and is in detail described here.
In short it is relevant in this case and works like this:
First, user interaction is not possible with a daemon application,
which requires the application to have its own identity. An example of
a daemon application is a batch job, or an operating system service
running in the background. This type of application requests an access
token by using its application identity and presenting its Application
ID, credential (password or certificate), and application ID URI to
Azure AD. After successful authentication, the daemon receives an
access token from Azure AD, which is then used to call the web API.
Have a look at this implementation to see how it is done in code.
Using OAuth On-Behalf-Of works exactly what you describe. Which On-Behalf-Of method, there is no user interaction to obtain the user's consent to access to the downstream API (e.g. Graph API). In other words, the user identity & permission is silently delegated in a full request chain. In a real-world corporate environment, your app would be normally authenticated by another identity provider (e.g. Active Directory) not Azure AD, which after then requests authorization to Azure AD OAuth endpoint.
When requesting access token, you must set its type is requested_token_use=on_behalf_of
Here is reference to POST to the endpoint https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-protocols-oauth-on-behalf-of
Here is the reference of SSO authentication with OAuth On-Behalf-Of https://learn.microsoft.com/en-us/outlook/add-ins/authenticate-a-user-with-an-sso-token

Add claims into token Azure B2C

What are ways to include custom claims (user subscriptions or roles list as example) in a token before issuing it in Azure AD B2C, provided that claims are stored somewhere on own server (not available in B2C)?
Goal to have claims in the token to avoid additional round trip to the storage on every request.
Investigation on the topic brought me to following ways:
Add custom attribute via Graph API, configure to include in JWT. Attribute values should be kept in sync with our datastorage.
Custom Sign-In Policy like in this article https://learn.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-rest-api-step-custom but if I got it right, additional Step 6 is a user journey to publicly available API in non restricted way (request not secured by secret, might be used to get user claims by presented UserId)?
IdentityServer4 Federation gateway http://docs.identityserver.io/en/release/topics/federation_gateway.html that will allow to add any claims before issuing.
The first two mechanisms you outlined are the most common and recommended ways to include custom claims in an Azure AD B2C issued token:
Add a custom attribute and include it in the JWT. You can enable the custom attribute via the B2C UI or via the Graph API. You'd need to build your own mechanism to keep the value of this attribute in B2C in sync with your external source via the Graph API.
You can use a custom policy to add a step in your authentication flow to call a Rest API to obtain the claim and include it in the token. This call to the Rest API will be performed by the Azure AD B2C service and NOT the user's browser, so it'll be a service-to-service call (versus a client-to-service call), keeping any secrets you use for authentication with your Rest API safe (such as a Azure function code).

List users' Azure subscriptions

My application uses Azure AD and OpenID Connect to sign-in users (see https://github.com/Azure-Samples/active-directory-dotnet-webapp-openidconnect).
I want to be able to list users' Azure subscriptions when they've signed-in. I cannot figure what I need to do after a user has successfully signed-in and they've been redirected back to my app, i.e. how/where I get a hold of the necessary access token or credentials, and, to be honest, which is the correct API to call with said token/credentials. Can this be done? Is an entirely different approach necessary?
Look through the code in the example for an instance of AuthenticationResult. The access token can be accessed at AuthenticationResult.AccessToken and you can decide what you want to do based off that.
One of the notification events (raised as part of the sign-in flow) receives an authorization code. With the code, I was able to acquire an access token (using AuthenticationContext.AcquireTokenByAuthorizationCode) and, with that, I was able retrieve the subscriptions using this API https://management.azure.com/subscriptions. Note: ensure your AD application delegates permissions to the Service Management API.

Resources