IdentityServer4 Single Sign On with different scopes - oauth-2.0

Scenario:
b2c app with scope1 and scope2
b2b app with scope3 and scope4
Issue:
A user who can access both sites. If the user logs in on the b2b he will not have the b2c scope. So going to the b2c site the login will not be re-proposed but the jwt token will not have the scopes to call the Api of that context.
Is there a way to request additional scopes on a logged in user? Unfortunately I didn't find anything on the documentation.
Thanks for your help

Related

AAD B2C - User consent not asked

Context:
Azure AD B2C for a Tenant
External Identity Provider configured
B2C login flow (sign-in sign-up) configured
API backend defined as Application with 2 scopes in AAD B2C of this Tenant
"Admins and users" can consent
External client/Third Party app (confidential) defined as Application in AAD B2C of this Tenant
External client/Third Party app has permissions on the 2 scopes
Status is "nothing", I did not grant admin consent, I want the users to give consent themselves
In Enterprise applications | User settings
Users can consent to apps accessing company data on their behalf: YES
In Consent and permissions | User consent settings
=> Allow user consent for apps - All users can consent for any app to access the organization's data.
Authorize URL:
https://xxx.b2clogin.com/xxx.onmicrosoft.com/oauth2/v2.0/authorize
?p=B2C_1_signup_login
&client_id=xxx
&nonce=defaultNonce
&redirect_uri=xxx
&scope=offline_access%20openid%20profile%20email%20https%3A%2F%xxx.onmicrosoft.com%2F6D6E9DF9-4546-47D8-8EDB-D65EC89A0E90%2Fproduct_scope_2
&response_type=code
&code_challenge=ThisIsntRandomButItNeedsToBe43CharactersLong
&code_challenge_method=plain
User is redirected to external IDP provider, logs in. User is not asked for consent. Callback url is called with a code, which can be exchanged for an id_token. Audience (aud) is the client_id of the Client Application, not the API.
If I grant admin consent, the code can be exchanged for an access_token and id_token, and the audience is OK (API's client_id).
What must I configure to have the users asked to give consent, for the Client Application + the scopes? I haven't been able to find any article about this: user consent AND external identity provider.
You must do an Admin Consent in AAD B2C. It does not have an OAuth2.0 consent prompt for users. Instead it’s modelled with a terms of use. You never do an Oauth consent unless you share your data with a third party.
https://github.com/azure-ad-b2c/samples/blob/master/policies/terms-of-service
In Consent and permissions | User consent settings => Allow user consent for apps - All users can consent for any app to access the organization's data.
Irrelevant to AAD B2C apps.
If you still want some consent UX:
https://github.com/azure-ad-b2c/samples/tree/master/policies/service-consent

having an issue with Azure AD B2C sign in/set up

I am trying out Azure AD B2C by following the docs here: https://learn.microsoft.com/en-gb/azure/active-directory/develop/tutorial-v2-asp-webapp
I have created an ADB2C tenant directory, and I have created the test application. The sign in link seems to be fine. Then I add test users to the AD directly because I want to test signing in. When testing, I usually create email addresses in the following format: email+ADtest#mydomain.org. I add an user with such an email, a password, etc. Then from within my test application sign in screen, I try to sign in, but I always get the error the username is not recognized.
Next, I add another user to the AD directly: my personal email account, with a password. Now this time when I try to sign in with my app, it recognizes that email address as an account already registered with microsoft.com and tries to authenticate me that way. But this is not what I want. I only want the email accounts whether they be user#microsoftonline.com or user#gmail.com to authenticate against the AD users I have setup with their passwords. I don't want microsoft to recognize them against their own database of users. How can I set this up?
Azure B2C and normal AAD are different.
See OAuth 2.0 authorization code flow in Azure Active Directory B2C and Normal AAD OAuth 2.0 authorization code flow.
We can find that the B2C authorize endpoint is https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/{policy}/oauth2/v2.0/authorize while AAD authorize endpoint is https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize.
We need to specify the B2C sign in policy when we integrate the B2C authentication.
So the document you are following doesn't apply to B2C scene. Please refer to Quickstart: Set up sign in for an ASP.NET application using Azure Active Directory B2C.

No access token returned for AD B2C user when requesting Microsoft Graph delegated permissions

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.

Access to user's mailbox using EWS, OAuth2 and user's credentials

In our application we use EWS and basic authentication.
An user can get access to own mailbox only or to all mailboxes in his organization if he has admin credentials. Now we are trying to replace basic authentication with OAuth2 authentication.
We registered the application on Azure portal, added the permission "EWS.AccessAsUser.All".
For an admin account everything works well. Our application can get access to any mailbox in admin's organization.
The problem is in that we cannot get an authorization code for a standard user account.
"TestApp needs permission to access resources in your organization that only an admin can grant" is shown.
So the question is: is there a way to get access to user's mailbox using EWS, OAuth2 and user's credentials?
With oAuth you need to grant consent for your application in a Tenant eg
https://learn.microsoft.com/en-us/azure/active-directory/manage-apps/grant-admin-consent once you have granted tenant wide consent any user should be able to use the application unless you apply restrictions. If your application is being used by other companies then you need to have a Multi Tenant application registration and the client will need to consent to its use in their tenant before they can use it.

In the Microsoft Graph API, can an app with admin consent generate a token for a different user than the admin that approved it?

I have a multi tenant app registered in Microsoft Active Directory that uses admin consent to gain access to some application scope APIs in the Microsoft Graph API. It uses the /token endpoint to get a token, then calls those Graph APIs. It's working perfectly.
https://learn.microsoft.com/en-us/graph/auth-v2-service#token-request
Now I want to enhance my app to access some delegated (user) scope APIs, that do not allow access at application scope. My app is already configured to request these delegated permissions from the admin at admin consent time. But I'd like to call these APIs as each user in the directory, not the admin who installed my app.
Importantly, it is not feasible for me to have every user in the organization individually go through the OAuth flow for my app.
Is that possible?
Can I impersonate a user somehow by exchanging my application token for a user token?
Can the admin do something programmatically to generate tokens as individual users for my app as if they had been put through an OAuth flow?
No, you cannot convert an Application token to a Delegated token. The only way to act as a specific User is for that User to "delegate" those activities to your application.
Note that Admin Consent only provides consent to your App to operate within a tenant. It is destinct from, not a superset of, User Consent. In order to obtain a Delegated token, you need to receive both User and Admin consent.

Resources