I was trying to create a user in Azure AD without mail filed is user created successfully. I need to add the email id in Azure AD at the time of user created.
I added the mail property in json and it says
Property 'mail' is read-only and cannot be set.
My C# code is:
var url = string.Format("https://graph.windows.net/{0}/users?api-version=1.6",oauthsettings.TenantId);
var authDetails = _orchardServices.WorkContext.CurrentSite.As<AzureAuthenticationPart>();
var alogin = new AzureLogin();
var jwttoken = alogin.ServiceAuth(authDetails.ClientId, authDetails.ClientSecret);
var aadUser =new {
mail=email,
accountEnabled = true,
displayName = userName,
mailNickname = userName,
passwordProfile = new passwordProfile()
{
password = password,
forceChangePasswordNextLogin = authDetails.IsUpdatePwdNextLogin
},
userPrincipalName = userName + oauthsettings.DirectoryName,
};
var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + jwttoken);
var modelval = Convert.ToString(JsonConvert.SerializeObject(aadUser));
var content = new StringContent(modelval, Encoding.UTF8, "application/json");
var result = client.PostAsync(url, content).Result;
Get Access Token from Azure AD After Login
JwtSecurityToken token = GetAccessToken(authDetails, code, returnUrl);
var claims = token.Claims;
return LogOn(claims, returnUrl);
Getting Email from JWT
public LogOnResponse LogOn(IEnumerable<System.Security.Claims.Claim> claims, string returnUrl)
{
var email = claims.FirstOrDefault(s => s.Type == "email").Value;
In this place I can't get the access token, because the user created time is not set the email in Graph API Request. I have another problem is this email id based only I was validate another site also, so I was required set the email in user created time.
I required email id for login in my application. i was integrate the Azure AD in existing application it's required for email.
Does anyone know how to set the email id in Azure AD for a user.
My Request in Postman. Response for Email Added in Request
Because the mail attribute is tied to Exchange Online, we don't permit you to write to that attribute unless you have an Exchange Online license. When you activate a license for the user, Exchange Online will update the field with the correct mailbox mail address during the creation of the user's mailbox. You can utilize "MailNickName" and " other emails" during the creation of a user. This field will also depend upon if it is a "local account (B2C)" or "work or school account".
I hope this answers your question concerning the "mail" attribute being "read-only"
There are two different fields for Email Addresses on an AAD User.
From the Graph API Reference:
mail
POST, GET ($filter)
The SMTP address for the user, for example, "jeff#contoso.onmicrosoft.com".
otherMails
POST, GET ($filter), PATCH
A list of additional email addresses for the user; for example: ["bob#contoso.com", "Robert#fabrikam.com"].
Note that you can only set the mail property when you initially create the user (POST), but you can update the otherMails property whenever you want (PATCH).
It seems like you should be using the otherMails property for your needs.
Related
I'm having trouble in adding custom claim (tenant id) to my token. So my program allows users to switch their workspace using tenant id. In order to do that I need to receive the selected Tenant Id and generate new token with the selected tenant id inside the token.
To generate the token first time during login, I used this code
var tokenResponse = await httpclient.RequestPasswordTokenAsync(new PasswordTokenRequest
{
Address = discoveryDocument.TokenEndpoint,
UserName = model.PhoneNumber,
Password = model.Password,
ClientId = Configuration["ClientInformation:ClientId"],
ClientSecret = Configuration["ClientInformation:ClientSecret"]
});
And to generate new token after they login to switch the tenant, I used refresh token.
var tokenResponse = await httpclient.RequestRefreshTokenAsync(new RefreshTokenRequest
{
Address = discoveryDocument.TokenEndpoint,
ClientId = Configuration["ClientInformation:ClientId"],
ClientSecret = Configuration["ClientInformation:ClientSecret"],
RefreshToken = model.RefreshToken
});
I already seen how profile service receive data using claimsprincipal and thats where I was confused how to insert new value inside the claimsprincipal
So my question is how do I send the selected tenant id to profile service?
I'm able to do this by saving the tenant id that the user wants to the database and I'm able to get the tenant value using profile service
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.
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 need a server-side task on my .NET 4.6.1/MVC 5 app that will periodically check a specific O365 email address for new emails and retrieve them if found. This seems like a stupidly simple task, but I cannot find documentation anywhere for creating a server-side process to accomplish this. The only documentation Microsoft seems to have is for OAuth2 and passing through credentials when users sign in. I don't want that. I want to check one specific account, that's it. How would I accomplish this?
These are the pages I've found. There are others, but all are along these lines.
Intro to the Outlook API - I don't see a way to use a service account with the v2 endpoint.
Get Started with the Outlook REST APIs - This is specific to logging users in with OAuth2, unhelpful for my purposes.
Intro to the Outlook API - I don't see a way to use a service account with the v2 endpoint.
The v2 endpoint doesn’t support client credential at present( refer to the limitation). You need to register/configure the app using Azure portal and use the original endpoint to authenticate the app. More detail about register the app please refer to here. And we need to ‘read mail in all mailbox’ to use the client credential to read the messages like figure below.
And here is the code that using client credential to read messages using the Microsoft Graph:
string clientId = "";
string clientsecret = "";
string tenant = "";
string resourceURL = "https://graph.microsoft.com";
string authority = "https://login.microsoftonline.com/" + tenant + "/oauth2/token";
string userMail = "";
var accessToken = new TokenHelper(authority).AcquireTokenAsync(clientId, clientsecret, resourceURL);
var graphserviceClient = new GraphServiceClient(
new DelegateAuthenticationProvider(
(requestMessage) =>
{
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", accessToken);
return Task.FromResult(0);
}));
var items = await graphserviceClient.Users[user].Messages.Request().OrderBy("receivedDateTime desc").GetAsync();
foreach (var item in items)
{
Console.WriteLine(item.Subject);
}
class TokenHelper
{
AuthenticationContext authContext;
public TokenHelper(string authUri)
{
authContext = new AuthenticationContext(authUri);
}
public string AcquireTokenAsync(string clientId, string secret,string resrouceURL)
{
var credential = new ClientCredential(clientId: clientId, clientSecret: secret);
var result = authContext.AcquireTokenAsync(resrouceURL, credential).Result;
return result.AccessToken;
}
}
In addition, if we authenticate the app with code grant flow we can also create a subscription which notify the app when the mail box receive the new messages.( refer to webhoocks/subscription)
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);