I want to invite an user in our Active Directory/Tenant. For this using Micorosoft Graph API. Code is used as below
IConfidentialClientApplication confidentialClientApplication = ConfidentialClientApplicationBuilder
.Create(clientId)
.WithTenantId(tenantID)
.WithClientSecret(clientSecret)
.Build();
ClientCredentialProvider authProvider = new ClientCredentialProvider(confidentialClientApplication);
GraphServiceClient graphClient = new GraphServiceClient(authProvider);
var invitation = new Invitation
{
InvitedUserEmailAddress = "myemailaddress#gmail.com",
InviteRedirectUrl = "https://myapp.com"
};
await graphClient.Invitations
.Request()
.AddAsync(invitation);
After this, I can see the user in Azure's Active directory portal. But don't get an invitation email.
However, when I click on Resend Invite from Azure Portal then the invite email is coming.
Can you please guide, why the invite email is not coming when sending invite from API?
You need to set SendInvitationMessage to true in your Invitation object:
var invitation = new Invitation
{
InvitedUserEmailAddress = "myemailaddress#gmail.com",
InviteRedirectUrl = "https://myapp.com",
SendInvitationMessage = true
};
For more info you can read the Docs
sendInvitationMessage Boolean Indicates whether an email should be
sent to the user being invited or not. The default is false.
Related
I am trying to send mail on behalf of some users using the Microsoft Graph API through my Winforms application. I registered the app in Application Registration at Azure Portal in my tenant and assigned application permissions for sending mail to the app. I am using client credentials flow for sending mail.
The mail is successfully sent when sending the mail on behalf of my tenant user. Then I granted the admin consent to my app from another tenant and tried to send mail on behalf of that tenant's user but I get an error
Code: ErrorInvalidUser
Message: The requested user 'foo#tenanttwo.onmicrosoft.com' is invalid.
That user has a valid license of O365.
Can we send the mail on behalf of other tenant's user using the Microsoft Graph API? If yes then please help me what else I need to do?
This is the code I'm using:
var scopes = new[] { "https://graph.microsoft.com/.default" };
// using Azure.Identity;
var options = new TokenCredentialOptions
{
AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
};
// https://learn.microsoft.com/dotnet/api/azure.identity.clientsecretcredential
var clientSecretCredential = new ClientSecretCredential(tenantID, clientId, clientSecret, options);
var graphClient = new GraphServiceClient(clientSecretCredential, scopes);
var message = new Microsoft.Graph.Message
{
Subject = strSubject,
Body = new ItemBody
{
ContentType = BodyType.Text,
Content = strBody
},
ToRecipients = new List<Recipient>()
{
new Recipient
{
EmailAddress = new EmailAddress
{
Address = strTo
}
}
}
};
var saveToSentItems = true;
await graphClient.Users[senderMail]
.SendMail(message, saveToSentItems)
.Request()
.PostAsync();
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'm trying to get my information using the Graph API SDK for C# (the idea is the application running without user interaction), as shows code sample below:
IConfidentialClientApplication confidentialClientApplication = ConfidentialClientApplicationBuilder
.Create("xxx")
.WithTenantId("xxx")
.WithClientSecret("xxx")
.Build();
ClientCredentialProvider authProvider = new ClientCredentialProvider(confidentialClientApplication);
GraphServiceClient graphClient = new GraphServiceClient(authProvider);
var user = await graphClient.Me.Request()
.Select(u => new
{
u.DisplayName,
u.Mail,
u.UserPrincipalName
})
.GetAsync();
It's returning 'WaitingForActivation' on Status, I don't know where is the problem.
This is not like you think. If you call the /me endpoint, you must log in the user. It actually obtains the logged-in user information, so you cannot use the client credential flow to obtain the access token. For the client credential flow, it is usually used for server-to-server interactions that must run in the background and do not interact with the user immediately(No user logged in). For the /me endpoint, it needs to accept the user token, because it has user interaction. So, I suggest you use auth code flow to get access token,which requires you to log in to the user and obtain the authorization code, and then use the authorization code to redeem the access token.
Authorization code provider:
IConfidentialClientApplication confidentialClientApplication = ConfidentialClientApplicationBuilder
.Create(clientId)
.WithRedirectUri(redirectUri)
.WithClientSecret(clientSecret) // or .WithCertificate(certificate)
.Build();
AuthorizationCodeProvider authProvider = new AuthorizationCodeProvider(confidentialClientApplication, scopes);
By the way, if you want to get user information in a scenario where no user is logged in, you can call the /users endpoint:
IConfidentialClientApplication confidentialClientApplication = ConfidentialClientApplicationBuilder
.Create("xxx")
.WithTenantId("xxx")
.WithClientSecret("xxx")
.Build();
ClientCredentialProvider authProvider = new ClientCredentialProvider(confidentialClientApplication);
GraphServiceClient graphClient = new GraphServiceClient(authProvider);
var user = await graphClient.Users["{userId or userPrincipalName}"].Request()
.Select(u => new
{
u.DisplayName,
u.Mail,
u.UserPrincipalName
})
.GetAsync();
Unable send mail using Microsoft-Graph-API (Azure AD B2c).
I have tried following code but not working
IConfidentialClientApplication confidentialClientApplication = ConfidentialClientApplicationBuilder
.Create(appId)
.WithTenantId(tenantId)
.WithClientSecret(clientSecret)
.Build();
ClientCredentialProvider authProvider = new ClientCredentialProvider(confidentialClientApplication);
GraphServiceClient graphClient = new GraphServiceClient(authProvider);
Message message = new Message
{
Subject = "Subject of mail",
Body = new ItemBody
{
ContentType = BodyType.Text,
Content = "Mail content",
},
ToRecipients = new List<Recipient>
{
new Recipient
{
EmailAddress = new EmailAddress
{
Address = email,
}
}
},
};
await graphClient.Me.SendMail(message).Request().PostAsync();
It gives following error :
Code: OrganizationFromTenantGuidNotFound
Message: The tenant for tenant guid 'xxxxxx' does not exist.
Inner error:
AdditionalData:
requestId: 0ecdb3f9-a210-4259-bd62-0c79e757d1f6
date: 2020-08-05T02:17:07
request-id: 0ecdb3f9-a210-4259-bd62-0c79e757d1f6
ClientRequestId: 0ecdb3f9-a210-4259-bd62-0c79e757d1f6
Note : Also Given permission for Mail.Send
This is because your Azure AD B2C tenant doesn't have an Exchange online license under O365 subscription.
So the B2C user doesn't have a mailbox to send the email although its UPN looks like an email address.
Try to assign an O365 subscription to the tenant and add an Exchange online license to the B2C user if possible.
We have an application developed in ASP.NET MVC. We also have Acitve Directory configured in Azure and it has some Groups into it.
Requirement is, we need to fetch all users from Azure Active Directory's Group and add a new user into it.
We are using code below and it is asking extra authentication I guess. we want to provide all authentication in code it self without giving popup wondow to authenticate. Can you please help with this
// Build a client application.
IPublicClientApplication publicClientApplication = PublicClientApplicationBuilder
.Create("clientID")
.WithTenantId("tenantId")
.Build();
// Create an authentication provider by passing in a client application and graph scopes.
DeviceCodeProvider authProvider = new DeviceCodeProvider(publicClientApplication, new[] { "User.Read" });
// Create a new instance of GraphServiceClient with the authentication provider.
GraphServiceClient graphClient = new GraphServiceClient(authProvider);
var members = await graphClient.Groups["groupId"].Members
.Request()
.GetAsync();
Above code shows a message as
"To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code G9277ULC9 to authenticate."
How can we provide all authentication information in code itself to avoid this step?
Updated
API permissions are as below -
Thank you in advance.
You could use the Microsoft Graph SDK to do that.
List members of a group:
GraphServiceClient graphClient = new GraphServiceClient( authProvider );
var members = await graphClient.Groups["{id}"].Members
.Request()
.GetAsync();
Add member to a group:
GraphServiceClient graphClient = new GraphServiceClient( authProvider );
var directoryObject = new DirectoryObject
{
AdditionalData = new Dictionary<string, object>()
{
{"#odata.id","https://graph.microsoft.com/v1.0/directoryObjects/{id}"}
}
};
await graphClient.Groups["{id}"].Members.References
.Request()
.AddAsync(directoryObject);
Update:
If you want a non-interactive way, you need to use the client credential flow, i.e. create the authProvider instance as Client credentials provider.
IConfidentialClientApplication confidentialClientApplication = ConfidentialClientApplicationBuilder
.Create(clientId)
.WithTenantId(tenantID)
.WithClientSecret(clientSecret)
.Build();
ClientCredentialProvider authProvider = new ClientCredentialProvider(confidentialClientApplication);