Is it possible to add local account to Azure AD B2C using the Microsoft.Graph SDK?
The Microsoft Graph API documentation requires that this data is sent (distinct members from that of work/school account).
I tried this:
User createdUser = graphClient.Users.Request().AddAsync(new User
{
AccountEnabled = true,
DisplayName = "TestUser",
PasswordProfile = new PasswordProfile
{
ForceChangePasswordNextSignIn = false,
Password = "Abcd#1234"
},
UserPrincipalName = "testuser#test.com",
MailNickname = "testuser#test.com",
}).Result;
But it just returns an exception of ServiceException: Code: InternalServerError Message: The given key was not present in the dictionary.
There is Microsoft.Azure.ActiveDirectory.GraphClient but is this not being deprecated? A lot of the "old" samples mention: "It is recommended for new projects to use Microsoft.Graph SDK", or words to that effect, at the top of them.
Currently.. You can't.
See here and here
Related
Using the Microsoft Graph API in C# I can successfully get a user's details and update say their first name, or details held in extension attributes. However, is it possible to update the email address that they use to sign in with?
I can see this held in the Identities section, but I can't see a way of updating the values held there.
is it possible to update the email address that they use to sign in
with?
if you refer to User.identities property which:
Represents the identities that can be used to sign in to this user
account.
then yes it is supported to update this property.
Note: Updating the identities property requires the
User.ManageIdentities.All permission
PATCH https://graph.microsoft.com/v1.0/users/{id-or-upn}
{
"identities": [
{
"signInType": "emailAddress",
"issuer": "{tenant-name}",
"issuerAssignedId": "{user-signIn-email}"
}
]
}
C# example
var tenant = "contoso.onmicrosoft.com";
var existingEmailAddress = "current_email#contoso.com";
var newEmailAddress = "new_email#contoso.com";
//1 . find user
var users = await graphClient.Users
.Request()
.Filter($"identities/any(c:c/issuerAssignedId eq '{existingEmailAddress}' and c/issuer eq '{tenant}')")
.Select("displayName,id,userPrincipalName")
.GetAsync();
var foundUser = users.FirstOrDefault();
//2. update user identity
var user = new User
{
Identities = new List<ObjectIdentity>()
{
new ObjectIdentity
{
SignInType = "emailAddress",
Issuer = tenant,
IssuerAssignedId = newEmailAddress
}
}
};
await graphClient.Users[foundUser.Id].Request().UpdateAsync(user);
userPrincipalName is the field that you need to update. As per Update User Docs Using body below works for me.
PATCH https://graph.microsoft.com/v1.0/users/{USER-ID}
{
"userPrincipalName": "alias#domain.com"
}
Add this field to the C# call and should work.
Is it possible to reset the user password created on my b2c tenant?
Trying to find something on the documentation here https://learn.microsoft.com/en-us/azure/active-directory/develop/msal-overview, but I couldn't find it. Maybe I am blind, so can someone point how to do it?
You could reset the password with this Microsoft Graph API.
When updating the passwordProfile property, the following permission is required: Directory.AccessAsUser.All.
GraphServiceClient graphClient = new GraphServiceClient( authProvider );
var user = new User
{
BusinessPhones = new List<String>()
{
"+1 425 555 0109"
},
OfficeLocation = "18/2111"
};
// If authorize without user, you need to add application permission. graphClient.Users[user-object-id].Request().UpdateAsync(user);
await graphClient.Me
.Request()
.UpdateAsync(user);
I created a console application to create an Azure AD user as follows (doc referred: https://learn.microsoft.com/en-us/graph/api/user-post-users?view=graph-rest-1.0&tabs=http):
static async Task Main(string[] args)
{
var credential = new ClientCredential("<clientt-id>", "<client-seceret>");
var authProvider = new HttpRequestMessageAuthenticationProvider(
credential,
"https://login.windows.net/<tenant-id>",
"https://graph.microsoft.com/");
GraphServiceClient graphClient = new GraphServiceClient(authProvider);
var user = new User
{
AccountEnabled = true,
DisplayName = "Test User",
MailNickname = "testuser",
UserPrincipalName = "testuser#M365xxxxxxx.onmicrosoft.com ",
PasswordProfile = "xxxxxxxxxxxx"
OnPremisesImmutableId = "id"
};
await graphClient.Users
.Request()
.AddAsync(user);
}
API permissions added to app are Group.ReadWrite.All and User.ReadWrite.All.
On running this code, I see the following error:
Code: Authorization_RequestDenied
Message: Insufficient privileges to complete the operation.
What am I missing?
For this problem, I summarize the points below which you need to check:
1. It seems your code use client_credentials as grant flow to do the job, so please check you have added the permissions of "Application" but not "Delegated". And don't forget grant admin consent.
2. If still show Authorization_RequestDenied message, please remove the permission Group.ReadWrite.All because this permission is unnecessary. And the Group permission may affect other permissions in my past tests.
3. It seems you develop the specific code in class HttpRequestMessageAuthenticationProvider, actually there is an off-the-shelf SDK avaiable for us to use. I provide my code below for your reference, the code works fine to create a user.
using Microsoft.Graph;
using Microsoft.Graph.Auth;
using Microsoft.Identity.Client;
using System;
using System.Threading.Tasks;
namespace ConsoleApp23
{
class Program
{
static async Task Main(string[] args)
{
Console.WriteLine("Hello World!");
IConfidentialClientApplication confidentialClientApplication = ConfidentialClientApplicationBuilder
.Create("<client_id>")
.WithTenantId("<tenant_id>")
.WithClientSecret("<client_secret>")
.Build();
ClientCredentialProvider authProvider = new ClientCredentialProvider(confidentialClientApplication);
GraphServiceClient graphClient = new GraphServiceClient(authProvider);
var user = new User
{
AccountEnabled = true,
DisplayName = "huryAdd",
MailNickname = "huryAdd",
UserPrincipalName = "huryAdd#xxx.onmicrosoft.com",
PasswordProfile = new PasswordProfile
{
ForceChangePasswordNextSignIn = true,
Password = "Password0123"
},
OnPremisesImmutableId = "testOnPre"
};
await graphClient.Users.Request().AddAsync(user);
Console.WriteLine("====success====");
}
}
}
And also provide the packages installed in my project.
Install-Package Microsoft.Identity.Client -Version 4.16.1
Install-Package Microsoft.Graph
Install-Package Microsoft.Graph.Auth -IncludePrerelease
4. By the way, there is a blank space in the end of your UserPrincipalName. Please remove it, otherwise it will show invalid principal name.
Hope it helps~
I had the same issue and managed to solve it.
I used the Directory.ReadWrite.All permission but still experienced the problem with setting the OnPremisesImmutableId attribute for our users.
After a bit of investigation, it turned out that i had to assign the roles "Group Administrator" and "User Administrator" to my application in Azure AD Portal (Azure AD > Roles and administrators > Click each group > Add Assignments). After both these roles had been applied to my application, the problem disappeard.
I have an Azure Account, now I'm trying to get token in an console application to manage resources (i.e. create a resource group etc):
string userName = "xyz#gmail.com";
string password = "XXXXXXXXX";
string directoryName = "xyzgmail.onmicrosoft.com";
string clientId = "guid-of-registered-application-xxx";
var credentials = new UserPasswordCredential(userName, password);
var authenticationContext = new AuthenticationContext("https://login.windows.net/" + directoryName);
var result = await authenticationContext.AcquireTokenAsync("https://management.core.windows.net/", clientId, credentials);
On AcquireTokenAsync call I have
Microsoft.IdentityModel.Clients.ActiveDirectory.AdalServiceException:
'accessing_ws_metadata_exchange_failed: Accessing WS metadata exchange
failed'
Can anybody help, please?
Update: how I tried to create a resource group under newly created user
var jwtToken = result.AccessToken;
string subscriptionId = "XX-XX-XX-YY-YY-YY";
var tokenCredentials = new TokenCredentials(jwtToken);
var client = new ResourceManagementClient(tokenCredentials);
client.SubscriptionId = subscriptionId;
var rgResponse = await client.ResourceGroups.CreateOrUpdateWithHttpMessagesAsync("myresgroup77777",
new ResourceGroup("East US"));
Here I got another exception
'The client 'newaduser#xyzgmail.onmicrosoft.com' with object id
'aaa-aaa-aaa-aaa' does not have authorization to perform action
'Microsoft.Resources/subscriptions/resourcegroups/write' over scope
'/subscriptions/XX-XX-XX-YY-YY-YY/resourcegroups/myresgroup77777'.'
Not sure why you're getting the first error, but the second error is because the signed in user does not have permission to perform the operation (as mentioned in the error message).
When you assign the permission to execute Windows Azure Service Management API, it is actually assigned to the application which assumes the identity of the signed in user.
In order to perform Create Resource Group operation in Azure Subscription, that user must be in a role that allows this operation to be performed. You can try by assigning built-in Contributor role at the Azure Subscription level to this user.
Also, regarding using login.windows.net v/s login.microsoftonline.com, it is recommended that you use latter. When you use login.windows.net, it gets automatically redirected to login.microsoftonline.com. Using login.microsoftonline.com will save you one redirection.
I am working on a WCF service where I need to sync the users from Windows Active Directory to a Salesforce account. I don't want to use any 3rd party tool or service, but want to develop a new one. I tried to use Partner WSDL provided by salesforce, but couldn't get how I can utilize it to create a new user in salesforce. Please give me some pointer on how I can utilize Web/REST API to create a new user in salesforce. Any sample code or link which can explain it.
For Salesforce's REST API you can use SalesforceSharp.
The sample code below will create an user on your Salesforce account:
var client = new SalesforceClient();
var authenticationFlow = new UsernamePasswordAuthenticationFlow
(clientId, clientSecret, username, password);
client.Authenticate (authenticationFlow);
var user = new
{
Username = "email#domain.com",
Alias = "userAlias",
// The ID of the user profile (Standard User, System Administrator, etc).
ProfileId = "00ei000000143vq",
Email = "email#domain.com",
EmailEncodingKey = "ISO-8859-1",
LastName = "lastname",
LanguageLocaleKey = "pt_BR",
LocaleSidKey = "pt_BR",
TimeZoneSidKey = "America/Sao_Paulo"
};
var id = client.Create ("User", user);