I have an Azure resource (Logic App) that uses its system-assigned identity to request a token from the Azure Active Directory. The Audience is an app-registration from the AAD. How can I attribute a scope to the system-assigned identity?
You could set scope as https://management.azure.com/.default when using AAD v2.0, or set resource as https://management.azure.com/ for AAD v1.0.
The scope is used for calling Azure Resource Manager Rest APIs.
Related
I'm exposing an API through Azure API Management. In order to call the API from the developer portal, an Authorization header with a bearer access token, issued by an Azure AD B2C instance, needs to be provided.
In the B2C instance, there is a signup/signin userflow (with connector API integration to load custom claims) that should be triggered by the APIM Oauth2 service configured for the API. This would mean that the user flow is triggered from within the developer portal (try it functionality) and the issued token is used to try out the API.
Who can point me in the right direction to get this working?
Remark: this is not an issue about setting up AAD B2C to get access to the developer portal, it is purely about calling our API from the developer portal (try it) with a token issued by our aad b2c instance.
I already tried to configure the b2c authorization endpoint with the signup/signin policy passed as query parameter but without success. I would expected is needed to pass in the policy to be used to ensure the right policy is ran ...
I have an application (Blazor WebAssembly in my case but I believe this scenario applies to other application types as well) that uses the excellent (and convenient) Azure B2C login services to allow my users to register and log in using either a local account or some social accounts. In particular, I am supporting logging in with a Microsoft account. Once a user is logged in using his Microsoft account I want to give the user the option to save content on OneDrive without the user having to provide credentials again to access the Microsoft Graph API.
In the returned claims after logging in using Azure B2C API I see that there is a idp claim (that's how I can determine if the user is logged in using a Microsoft account) and there is also a idp_access_token claim but it is not a valid JWT to use against the Microsoft Graph unfortunately.
What is the nature of the idp_access_token? How can I use it to access the Microsoft Graph and request additional scopes?
Azure AD B2C receives an access token (idp_access_token) from the identity provider. Azure AD B2C uses that token to retrieve information about the user. See details here.
No matter whether idp_access_token claim is a valid JWT, it cannot be used to access Microsoft Graph or other additional scopes. As the document has stated, it is for retrieving information about the user. Usually the embedded IdP access token is used to call the services that the IdP hosts. But Microsoft Graph data is hosted in Azure AD, not Microsoft Account side.
Currently, if you want to call Microsoft Graph API for B2C tenant, you have to follow Azure AD Authentication protocols. For example, OAuth 2.0 authorization code flow.
If you want to call you own API protected by B2C, you should choose Azure B2C Authentication protocols. For example, OAuth 2.0 authorization code flow in Azure Active Directory B2C.
User Story: Given an ADB2C User, with Global Administrator role and an oid of 01234567-901a-bcde-f012-3456789abcde (not a real oid), I want to be able to log in as that user and retrieve the user profile from "https://graph.microsoft.com/beta/me" or "https://graph.microsoft.com/beta/users/01234567-901a-bcde-f012-3456789abcde". Both are listed in the documentation as valid endpoints for B2C.
It's not working:
In an app registration with only Microsoft Graph permission scopes assigned, I used postman to request a bearer token for access to MS Graph. There is one Web redirect URI (https://oauth.pstmn.io/v1/callback), one client secret, and implicit grant is on for both access and id tokens.
The scopes requested are: openid offline_access https://graph.microsoft.com/Directory.AccessAsUser.All
Again, the B2C user account has the Global Administrator role.
The Implicit flow returns the error message
AADB2C90205: This application does not have sufficient permissions against this web resource to perform the operation.
The Authorization Code flow, when the app secret is included, lacks an access bearer token. There is an ID token and a refresh token, but no access token. That's with and without PKCE, whether or not I send the authorization to an external browser.
The app in my tenant has a user flow, B2C_1_postman, which is basically default. It works just fine with postman, other test apps, and the "Run User Flow" function in the B2C management blade.
The auth endpoint is:
https://{Tenant}.b2clogin.com/{Tenant}.onmicrosoft.com/B2C_1_postman/oauth2/v2.0/authorize
The token endpoint is:
https://{Tenant}.b2clogin.com/{Tenant}onmicrosoft.com/B2C_1_postman/oauth2/v2.0/token
I've duplicated this behavior with a couple of desktop demos from Microsoft's github repository, and now with Postman. The app, called "postman", is in the ADB2C tenant. I granted it the app API scopes of:
Directory.AccessAsUser.All
Directory.Read.All
Directory.ReadWrite.All
Directory.email
Directory.offline_access
Directory.profile
This procedure mirrors what the desktop demo at https://github.com/Azure-Samples/active-directory-b2c-dotnet-desktop sets up, with the single exception being that instead of a NodeJS sample app, I want my desktop app to use MS Graph. (This app registration works just fine if I add the endpoints for the sample app. But specifying the MS Graph scopes always returns an empty access ID.)
How can I get this to work?
Managing users through Graph API still seems to require usage of application permissions.
So instead of adding delegated permissions to the app in B2C, you need to add application permissions, where you call the Graph API as the app, not on behalf of the user.
The instructions in the docs explain the app registration in detail: https://learn.microsoft.com/en-us/azure/active-directory-b2c/microsoft-graph-get-started
You need to give this app application permissions to Graph API, not delegated permissions.
Then use those app credentials purely to call Graph API.
And you need to use the underlying Azure AD's token endpoint instead of your B2C policy token endpoint.
Since your app is a desktop app (a public client app), you'll need to do the Graph API interactions in a back-end service to which you can authenticate with a B2C token acquired on behalf of the user.
Mass confusion here.
You can definitely do what you are looking to do, except that this is all Azure AD functionality, not Azure AD B2C. So you are not looking to invoke any B2C user flow etc. B2C auths cannot get access to Microsoft APIs, only your own APIs.
AAD tenant - contains only AAD endpoints. It is a single token issuer
B2C tenant - contains both AAD and B2C token endpoints. There are two token issuers respectively
A B2C tenant contains:
AAD endpoint: login.microsoftonline.com THIS IS NOT BEING DEPRECATED
AAD B2C endpoint: tenantName.b2clogin.com+ B2C policyId parameter
Based on the authentication request, the request is routed to the two different token issuers.
The next key point:
AAD endpoints allow you to obtain tokens to your applications protected by an AAD Application Registration.
AAD endpoints allow you to obtain tokens to Microsoft APIs, since they are also protected by AAD on our side. Such as MS Graph API.
AAD endpoints allow client_credentials
B2C endpoints allow you to obtain tokens to your applications only protected by an AAD B2C Application Registration.
B2C endpoints do not allow client_credentials
You cannot use tenantName.b2clogin.com to obtain a token for MS Graph API, based on the above rule set.
This means a users B2C authentication cannot be used to authorize to AAD protected apps, or Microsoft APIs. (Eventhough the new App Reg experience allows assigning the permissions to MS Graph for B2C Application Registrations- we are looking to fix that).
When you use login.microsoftonline.com and don't provide any policy id parameters against a B2C tenant, you hit the AAD endpoints of the B2C tenant, again it works. You can get tokens to Microsoft Graph API for example, using the users context.
When you use tenantName.b2clogin.com and provide any policy id parameters against a B2C tenant, you hit the AAD B2C endpoints of the B2C tenant, now it will not work as you expected it to. Hopefully the above clarifies why. And since there is no deprecation of the AAD endpoint, you don't need to be using this domain name for this type of call.
The summary is, treat your scenario as a pure Azure AD scenario, as per this sample. You create an Application Registration for Accounts in this organizational directory only. when prompted for the type.
Can I define custom scope(s) and have them returned when using the client credential flow in Azure AD?
In my experiment, I configured 2 Azure AD applications, one for a Web API and one for a client (Web API Client A). I added a scope to the Web API but when requesting the access token via the client credential flow, the scope wasn’t returned. 🤔
Also, it only allowed me to request an access token when using .default for a scope, i.e. api://web-api-client-credential-flow/.default.
I ran across this Azure Feedback item: V2.0 Client Credentials Implement Scopes so it appears scopes aren't supported in Azure AD under the client credential flow?
What’s the point in giving my Web API Client A application permissions for that scope if they are not returned? How could the Web API know if the daemon application has that scope to perform the necessary action?
It would seem I would have to use application permissions?
Yes, you have to use application permissions.
Scopes aka delegated permissions only apply when a user is involved in the login process.
They allow you to act on behalf of a user.
Application permissions are sort of roles given to the application itself.
They only apply when doing client credentials authentication, where no user is involved.
You can define application permissions on the app via the Manifest in the app registration.
These can then be assigned to the client application.
When getting the token, you must use .default because you cannot change your app permissions dynamically.
You always get what has been granted already.
In the token the permissions will be in a roles claim.
Can I define custom scope(s) and have them returned when using the client credential flow in Azure AD?
No, but you can define application permission(s) via the manifest (definitely not as nice as the UI for delegated scopes) and have them returned via the client credential flow:
Then you can provide the client app permission:
Now when requesting a token with a scope of api://web-api-client-credential-flow/.default the "scopes" are returned in the roles claim. Sample JWT
Yes, you need to use api://web-api-client-credential-flow/.default for client credential flow.
And the application permissions will be returned in roles instead of scopes.
Microsoft Graph API provides App-only authentication scheme, which works perfectly for the tenant that owns an application.
I have an Azure tenant and I created the application inside it following documentation guide. My application is now able to obtain an access token using https://login.microsoftonline.com/<tenantId>/oauth2/token endpoint, which allows me to query the Graph API for the users inside my tenant.
However, I would like my application to be able to obtain access tokens for other tenants as well. I suppose the external tenant owner should somehow insert my application inside their Azure tenant, apply certain app-only scopes and provide me the tenant id in order to query the token endpoint.
Is multi-tenancy possible for app-only authentication scheme?
How does the tenant owner insert my application into their Azure tenant?
Multi-tenancy for app-only is possible, however, in order to enable this you require two things:
You need to have a web UI for the tenant admin to sign in to and perform admin consent in order to, as you called it, "insert my application into their Azure tenant." Make sure you add the query string parameter &prompt=admin_consent.
More info on admin consent: https://azure.microsoft.com/en-us/documentation/articles/active-directory-devhowto-multi-tenant-overview/#understanding-user-and-admin-consent
Sample controller method that "signs up" the user for an app via admin consent:
https://github.com/Azure-Samples/active-directory-dotnet-webapp-webapi-multitenant-openidconnect/blob/master/TodoListWebApp/Controllers/OnboardingController.cs#L33-L58
You will need to keep track of which tenants consented to your application so that you can enabled the code that runs the app-only flow for them. Unlike the delegated flow, you can't use the common endpoint (https://login.microsoftonline.com/common) but rather need to use the tenant specific endpoint for each instance or run of the app only flow.