Azure AD B2C Graph API: Create User + Login At Same Time - microsoft-graph-api

We are building an android/ios app that will authenticate with B2C. We will be creating our users programmatically with something like below:
API: invite user
USER: enters invite into app
API: confirms invitation info
USER: enters account info (i.e. password)
API + B2C/Graph: creates new user
USER: asked to login with new account (to get tokens) - will launch B2C hosted login
Question: Is there any way we could skip this last login step by using Graph to both create the user and get initial Access + Refresh tokens for the newly created user? See possible highlighted below.
My sense is that this is possible, but we'd need to mark our B2C application as Allow public client flows and then use the ROPC flow to get tokens programmatically on behalf of the user. This would likely lower the security posture of this B2C app somewhat. Are there other options?

Related

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.

Error AADSTS50034 when attempting to change password for local Azure AD B2C users with a username from an external domain

I am working on Azure AD B2C for my Angular 6 front-end App and consuming Microsoft Graph API in order to change the singed-in user's password. I am getting the access_token using the Authorization Code flow.
It works fine when the user has a username like xyz#myb2cname.onmicrosoft.com, I get an access_token and then call https://graph.microsoft.com/v1.0/users/{id}/changePassword.
But when I try to do the same for users with a username like xyz#gmail.com or abc#hotmail.com, I get an error when acquiring the access_token from Authorization Code flow (grant_type=password). Note: These users are "local" accounts in my AAD B2C tenant
Following is the error message I get:
{
"error": "invalid_grant",
"error_description": "AADSTS50034: To sign into this application the account must be
added to the myb2cname.onmicrosoft.com directory.
Trace ID: 8fcae061-5088-4393-9e5b-d0a83d1d0a00
Correlation ID: 0dc6c906-c54b-4cd8-ae8b-46f3f6118e40
Timestamp: 2018-08-01 06:16:55Z",
"error_codes": [
50034
],
"timestamp": "2018-08-01 06:16:55Z",
"trace_id": "8fcae061-5088-4393-9e5b-d0a83d1d0a00",
"correlation_id": "0dc6c906-c54b-4cd8-ae8b-46f3f6118e40"
}
How can I call changePassword for users who are signed in using the email identity provider (SignIn-SignUp Policy) when their username looks like xyz#gmail.com or abc#hotmail.com instead of xyz#myb2cname.onmicrosoft.com?
It is the expected behavior. You need to understand AD clearly before implementing it.
In Azure AD, to authenticate a user against a Directory, the user should be a part the Active Directory. The users, who are not a part of the Active Directory will not be authenticated. The token gets generated only when the user is authenticated.
Trying to generate a token for a user who is not a part of the Active Directory is similar to logging into Azure Portal with a invalid user account.
When an external user signs into your AAD, it does not create a traditional user with a traditional password, it creates a "guest" user. The actual user remains in the originating AAD tenant, your AAD tenant only stores a placeholder for that user.
You cannot change a guest user's password since your AAD doesn't actually have a password assigned to that user. Your AAD holds the authorization (what the user has access to) but relies on the user's AAD for authentication (the user is who they claim to be).
You can't change passwords for local account users using the Microsoft Graph API because, currently, an Azure AD B2C application can't be registered with the Microsoft Application Registration Portal and, therefore, it can't be used with the Microsoft Graph API.
You should change passwords for local account users using a custom policy.
This means the Azure AD B2C application doesn't have to collect either the current or new passwords for users.
I ran in the same situation where I was able to create and update the user in AZURE AD-B2C
but not able to delete or reset the password.
Because Currently, the Read and write directory data permission does NOT include the ability to delete users or update user passwords
Configure delete or update password permissions for your application
To archive this I had to follow the above link and it worked like a charm.

Suggest OAuth flow(grant type) or approach for below requirement

CompanyA is integrating with CompanyB where CompanyA's users will be buying devices of CompanyB.
CompanyA wants to show user's device(CompanyB) details on their app by calling
CompanyB's API on each user login.
CompanyA user is authenticated on CompanyA IAM.
CompanyA has to call register device when user tries to add an device first time.
Help me to identify the flow which i can use to query particular loggedin user's device only.
Do i need to create duplicate user account on CompanyB's IAM?
If i use client credential flow for API to API call, access token given by CompanyB is only provides access for API calls but it does not tell that on behalf of correct user only call is invoked.
Assume that CompanyA uses IdentityServer or any other provider as IAM and CompanyB uses Azure AD B2C.
Any other approach?
Please see below diagram,
You should be able to do this by making the Company B API multi-tenant in their Azure AD.
There are other options surely, this is just the first one that came to my mind.
Overview of the multi-tenant pattern
You would have to do admin consent on it to get the API's service principal in your Azure AD tenant.
The Company B API can give you an endpoint for doing this, redirecting you with the proper parameters to the authorization endpoint. How to send a sign-in request
After doing this, you should be able to then require permissions on the API from Company A API in your tenant (configured in Azure AD).
Configure a client application to access web APIs
After doing those things, your API should be able to use On-Behalf-Of grant flow to get an access token for Company B API.
Using Azure AD On-Behalf-Of flow in an ASP.NET Core 2.0 API
Company B API must be configured to accept access tokens from another issuer than their Azure AD of course.
In general multi-tenant scenarios, the issuer validation is commonly turned off.
If Company B wishes to have control over this, currently they will have to explicitly list the valid issuers.
Issuer values look like this: https://sts.windows.net/31537af4-6d77-4bb9-a681-d2394888ea26/, the GUID is your Azure AD tenant id.
The Company B API can extract the tenant id and user object id from the access token, and authorize the user to resources based on them.
I was looking at the AWS side and looks like they have something that could meet the requirements
https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_common-scenarios_federated-users.html
Was wondering if something like this exists in Azure.

How do I secure an account that is created via OAuth Spotify

I would like users to register an account on my site via OAuth Spotify. I have the following scheme:
User authenticates via Spotify
Spotify ID and Mail are returned
An account will be created on the website (saved to the database)
The user can log in with his Spotify to access that account
The problem I foresee here is that someone can spoof the authentication by copying the ID of another user and it's mail, am I right? If so, what would be a better way to let an user create an account using Spotify Authentication? Let the user set a password? That seems user unfriendly to me.
So, how can I achieve this?
You can use the access token acquired through OAuth to find the associated username. You can use this as the basis for your accounts instead of a username or password on your own site. The process would be something like:
The User authenticates via Spotify
The Spotify OAuth callback returns a authorization code
You use the authorization code to get an access and refresh token for the user
You use the access token to access the associated User ID and use this as the unique ID for the accounts on your site.
Save an account with the Spotify user ID to your site's database
The user can log in again with Spotify to access their account (it will streamline the process by skipping the Spotify OAuth view, if they have previously approved your site, and are logged into Spotify in their browser)
Since your application will only retrieve the User ID from someone's valid access token, and the only way your application will receive that is if they log in through the Spotify OAuth flow, each account on your site will be linked to a valid, unique, Spotify user.
While looking into this, there are security considerations about using OAuth alone to authenticate users. I would look at this post on Security Stack Exchange and decide based on what level of security is needed for your site.

DocuSign - Getting a user ID for a user whose organization admins has pre-authorized the application

Any route requires you to be authenticated as a DocuSign user to use it. With the standard service integration flow, you direct the user through docusign's /oauth/auth flow, use the returned code to get an access token via /oauth/token, then use that token on /oauth/userinfo to get the user's ID which you can then sign and use in a JWT.
Instead of directing users through the oauth UI to get their consent, DocuSign allows organization admins to pre-authorize an application for everyone in the application. No need to send organization members through the oauth flow. Great.
However, once this action has been taken, it's not clear how my application could make requests on behalf of any user, since the /oauth/userinfo route that gives you the user id requires an oauth code that you get by passing the user through DocuSign's oauth browser UI.
More specifically: if the admin of foo.com's DocuSign organization authorizes my app, and bob#foo.com starts using my application, how do I get bob#foo.com's user ID to create a JWT with?
When you say "bob#foo.com starts using my application" what, exactly, does that mean?
Case 1: Bob is interacting with your application. In that case, you should be using a User Application OAuth flow such as Authorization Code Grant to enable him to login.
If your app needs to later act on behalf of Bob when he's not around, then store Bob's user id for later use with the JWT grant.
Case 2: Your app is running in the background (no human interaction). At some point your app needs to starting doing things for Bob by impersonating him. All you have is his email address.
If this time arrives and your app has had no interaction with Bob, then yes, you need prior access as an admin (in Bob's account) so you can look up Bob's user_id from his email.
This second account would be the "admin user account" for your app. The account would need admin privileges to lookup the user's information. Your app would get access to this admin account when your app is installed.
Use the Users:list API call. Remember to encode the email address.
Example:
GET call: /v2/accounts/{accountId}/users?email=larry%2Buser%40foo.com
Re: user_id lifetime I'm reasonably sure that the user_id guid doesn't change for a given accounted user (someone who is a member of an account on DocuSign). I will check to make sure.

Categories

Resources