We're trying to create a user in Azure AD B2C (cloud tenant, not local) via the C# library. I cannot log in with the new user; it's saying the password has expired. From the AD B2C Sign-in log:
However, I'm creating them with password expiration disabled like so:
PasswordProfile passwordProfile = GetPasswordProfile(password);
var newB2cUser = new User
{
Id = id,
MailNickname = id,
UserPrincipalName = $"{id}#{tenant}",
GivenName = claims.FirstName,
Surname = claims.LastName,
DisplayName = displayName,
AccountEnabled = true,
PasswordProfile = passwordProfile,
PasswordPolicies = "DisablePasswordExpiration,DisableStrongPassword",
Identities = new List<ObjectIdentity>
{
new ObjectIdentity
{
SignInType = "emailAddress",
IssuerAssignedId = claims.Email,
Issuer = tenant
}
}
};
User createdB2cUser = await this.GraphServiceClient.Users.Request().AddAsync(newB2cUser);
...and with the password profile created like this:
private static PasswordProfile GetPasswordProfile(string password)
{
var passwordProfile = new PasswordProfile
{
Password = password,
ForceChangePasswordNextSignIn = false,
ForceChangePasswordNextSignInWithMfa = false
};
return passwordProfile;
}
We've used code like the above to create users all the time that need to reset their password on login. Now we need to create a user with a preset password that won't immediately expire (e.g., seeding a test environment). I added what I thought were the correct password policies and password profile above. What's going on?
I can see nothing wrong with the code sample you provided. But did you try achieving the same goal using Graph API directly? Just to understand what is going on and where the fault may be. You can use GraphExplorer: https://developer.microsoft.com/en-us/graph/graph-explorer
Invoke a POST request to the https://graph.microsoft.com/v1.0/users endpoint with the similar JSON to see whether you face the same issue.
{
"id": "fcaba916-17b0-4d88-84ea-03371d55067a",
"mailNickname": "MelissaD",
"userPrincipalName": "MelissaD#contoso.onmicrosoft.com",
"givenName": "Melissa",
"surname": "Darrow",
"displayName": "Melissa Darrow",
"accountEnabled": true,
"passwordPolicies": "DisablePasswordExpiration,DisableStrongPassword",
"passwordProfile": {
"password": "da413e48-180d-1945-6025-d7e5947711ed",
"forceChangePasswordNextSignIn": false,
"forceChangePasswordNextSignInWithMfa": false
},
"identities": [
{
"signInType": "emailAddress",
"issuer": "yourissuer",
"issuerAssignedId": "email"
}
]
}
Try to simulate the request body exactly as Graph Client does to know what is going on behind the scenes.
Related
I have a program which I create users through Microsoft graph in my Azure AD b2c
for normal users the code runs and creates AD b2c account
In the B2C I have admin users which are the Tenant administrators
When I try to create programatically accounts for the same user as b2c user I get error
Creating new user in Azure AD b2c error: Another object with the same value for property proxyAddresses already exists
but when I perform the same operation through GUI I can add 2 accounts with the same email.
the first is the user which is invited as admin and the second is the B2C normal user
var user = new User
{
AccountEnabled = true,
GivenName = "MJX",
Surname = MJX,
Mail = theEmail,
DisplayName = "Someting",
UserType = "Member",
CreationType = "LocalAccount",
PasswordProfile = new PasswordProfile
{
ForceChangePasswordNextSignIn = true,
Password = GeneratedPassword,
},
PasswordPolicies = "DisablePasswordExpiration",
Identities = new List<ObjectIdentity>
{
new ObjectIdentity()
{
SignInType = "emailAddress",
Issuer = tenantName,
IssuerAssignedId = theEmail
}
}
};
//insert into AD
var createdUser = graphServiceClient.Users
.Request()
.AddAsync(user).GetAwaiter().GetResult();
Removed the Mail property it worked for me
//Mail = theEmail
After successfully Authenticated using MSAL. I get the token and passed it on the Flurl. I'm getting 500 error. But if I test it on Postman it works properly. Anything I missed?
Below is my code:
var user = new User
{
AccountEnabled = true,
DisplayName = "Anthony Test",
MailNickname = "AnthonyT",
UserPrincipalName = "AnthonyT#*****.onmicrosoft.com",
PasswordProfile = new PasswordProfile
{
ForceChangePasswordNextSignIn = true,
Password = "xWwvJ]6NMw+bWH-d"
}
};
var result2 = await "https://graph.microsoft.com/v1.0/users".WithHeader("Content-Type", "application/json")
.WithOAuthBearerToken(result.AccessToken)
.PostJsonAsync(user);
Here is a screenshot from Postman:
I have fixed the issue. I forgot to set JsonProperty and make it camelCase.
I'm trying to add users in an Azure AD B2C using the Microsoft Graph API. My code works just fine when I add a User, but I tried to add it a second time with the same info given to the API (mail, names, etc...) and expected an error like
User already exists
or something similar.
My API call is done like this :
var result = await graphClient.Users.Request().AddAsync(new User()
{
AccountEnabled = true,
Mail = "example#example.onmicrosoft.com",
MailNickname = "example",
UserPrincipalName = "example#example.onmicrosoft.com",
Surname = "TEST",
DisplayName = "test",
GivenName = "TEST test",
PasswordProfile = new PasswordProfile
{
ForceChangePasswordNextSignIn = true,
Password = "tmpPwd"
}
});
Keeping in mind that my first call correctly add the user to the AD, why the API would return me this message :
Microsoft.Graph.ServiceException : 'Code: Request_BadRequest
Message: One or more properties contains invalid values.
Thank you in advance.
According to the document Create the user using the below property without mail .so that when a user has already existed then you will get the error as below
Code: Request_BadRequest
Message: Another object with the same value for property userPrincipalName already exists.
code:
var result = await graphClient.Users.Request().AddAsync(new User()
{
AccountEnabled = true,
MailNickname = "example",
UserPrincipalName = "example665#XX.live",
Surname = "TEST",
DisplayName = "test",
GivenName = "TEST test",
PasswordProfile = new PasswordProfile
{
ForceChangePasswordNextSignIn = true,
Password = "password#1234"
}
});
Console.WriteLine(JsonConvert.SerializeObject(result));
}
Using additional property may change the error context as you are receiving currently
We are using ADAL.Net to create users in Azure AD. using SinginNames, we can provide any email address (gmail or non-domain emails) as username to create Azure AD Local account.
when we try the same using Microsoft Graph (MSAL.Net), we are not able to create a user:
Code: Request_BadRequest
Message: Property userPrincipalName is invalid.
How can we create gmail address as the username using Microsoft Graph or the Microsoft Graph Client Library?
The newly created account should be local user account, not a guest user.
var user = new User
{
AccountEnabled = true,
DisplayName = "displayName-value",
MailNickname = "mailNickname-value",
UserPrincipalName = "vetrivelmp1#gmail.com",
PasswordProfile = new PasswordProfile
{
ForceChangePasswordNextSignIn = true,
Password = "Test123!##"
}
};
var graphClient = await _msGraphHelper.GetMsGraphClientAsync();
var createdUser = await graphClient
.Users
.Request()
.AddAsync(user);
No You can not. You must have to request with tenant specific email following sample:
Request URL: https://graph.microsoft.com/v1.0/users
{
"accountEnabled": true,
"displayName": "KironTestDisplayName",
"mailNickname": "KironTestNickName",
"userPrincipalName": "KironTestingCreateUserWithMember#MyTenant.onmicrosoft.com",
"userType":"guest",
"passwordProfile" : {
"forceChangePasswordNextSignIn": true,
"password": "Test#pass420"
}
}
Points to Remember:
Get the proper token in which tenant you are going to create user
Need necessary request permission
userPrincipalName should follow as
UserName#tenant-value.onmicrosoft.com
"userType":"guest" Or "Member" You can add
Note: Mail should be like myUser#Mytenant.onmicrosoft.com Other then you would encounter 400 request error like Property userPrincipalName is invalid
Your Case:
If you wanted to create user using gmail account then request pattern need to be changed You have to request for invitation API like below:
Request Url: https://graph.microsoft.com/v1.0/invitations
Request Body:
{
"invitedUserEmailAddress": "TestGmailUser#gmailUser",
"inviteRedirectUrl": "https://myapp.com"
}
Response:
Note: If go to azure portal you would see you cannot add gmail user as domain member you add as guest user after invitation. So this
why you need above request pattern. Hope you are clear now.
Gmail User Add SDK:
GraphServiceClient graphClient = new GraphServiceClient( authProvider );
var invitation = new Invitation
{
InvitedUserEmailAddress = "TestGmailUser#gmailUser",
InviteRedirectUrl = "https://myapp.com"
};
await graphClient.Invitations
.Request()
.AddAsync(invitation);
Azure Portal Verify:
I have successfully added gmail user on my portal using above request. See the screen shot below:
For those still trying to accomplish this, the accepted answer here wasn't helpful, or at least is not the case here in 2021. I was able to create local B2C accounts with personal email addresses as well as custom sign in names using Example 2: Create a user with social and local account identities.
POST https://graph.microsoft.com/v1.0/users
Content-type: application/json
{
"displayName": "John Smith",
"identities": [
{
"signInType": "userName",
"issuer": "contoso.onmicrosoft.com",
"issuerAssignedId": "johnsmith"
},
{
"signInType": "emailAddress",
"issuer": "contoso.onmicrosoft.com",
"issuerAssignedId": "jsmith#yahoo.com"
},
{
"signInType": "federated",
"issuer": "facebook.com",
"issuerAssignedId": "5eecb0cd"
}
],
"passwordProfile" : {
"password": "password-value",
"forceChangePasswordNextSignIn": false
},
"passwordPolicies": "DisablePasswordExpiration"
}
I have a Azure Active Directory B2C tenant. I also have a small service that creates new users in the B2C tenant from a different system. This way I can synchornize both systems. When a user has been added to B2C and logs in the first time, I want the user to be forced to change the password. But whatever I do, the user can just log in and continue, without changing the password..
To add a user to B2C, I use the Microsoft Graph 1.14 package. I push the user information as JSON to the endpoint https://graph.windows.net/{tenantId}/users?api-version=1.6
The log in page is an Azure custom page in the user flow policies. There is also a change password policy, if needed.
This I tried:
When adding the user, I set the password profile. Adding the property "ForceChangePasswordNextLogin" and setting it to true, does not work.
Someone suggested to add the "ForceChangePasswordNextSignIn" property, but B2C doesn't know this property.
Tried to fix it in the policy; didn't work.
Used Google and StackOverflow; not much luck.
This is the user I post to Microsoft Graph:
var user = new GraphUserModel
{
City = "Amsterdam",
CustomField= "999999",
Department = "TestPassword",
DisplayName = "TestPassword",
OtherMails = new[] { "myemail#something.nl" },
PostalCode = "1234 AB",
StreetAddress = "Hoofdweg 6",
Surname = "TestPassword",
TelephoneNumber = "0123456789",
ChainCode = null,
MailNickname = "999999",
UserPrincipalName = "999999#{tenantNameHere}",
SignInNames = new List<SignInNames>
{
new SignInNames
{
Type = "userName",
Value = "999999"
}
},
AccountEnabled = true,
CreationType = "LocalAccount",
PasswordProfile = new PasswordProfile
{
Password = "SomeRandomPassword"
},
PasswordPolicies = "DisablePasswordExpiration"
};
The users are created correctly, but when they log in for the first time, I would like to see a page where they are forced to change the password.
With Sign-up/Sign-in policy I had to implement that manually by flagging users in DB if they have changed the password and then redirecting to password change if they have not changed the password.
I was also not able to find 'out of the box' solution. I found that forceChangePasswordNextLogin works only with Sign-in policy.