Microsoft Graph API 403 error Failed to get license - microsoft-graph-api

As part of an automated process to create teams and channels need to provision the email.
Provisioning the email is a delegated operation whereas the initial teams and channel creation is 'application' thus requires no user involvement.
Have created an 'automation' AD user with minimal system access and created the associtated Azure 'application' with the appropriate Graph permissions - and this works no problem however for the 'automation' user getting:
Failed to get license information for the user. Ensure user has a valid Office365 license assigned to them
The message is self explanatory - so the question is, is it possible to perform basic Teams graphAPI operations such as provisioning email addresses and maybe sending messages without an O365 license - something like a Guest account?
The following code works for accounts with o365 licenses:
var UserName = "automationbotuser#somewhere.com";
var Password= "2w234234##$$%^^&^&*(erfwerwepassword";
var TenantId= "azuretentant";
var Client_Id= "azureappclientid";
var teamId = "b2342300d12-923e-46sdfsd5e-ae98-9132424db2250bc";
var projectChannel = "19:e5fe8e53ee6brwerwf8b3323438ab59913ef42#thread.tacv2";
// using Azure.Identity;
var options = new TokenCredentialOptions
{
AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
};
//create credentials
var userNamePasswordCredential = new UsernamePasswordCredential(
UserName, Password, TenantId, Client_Id, options);
var graphClient = new GraphServiceClient(userNamePasswordCredential);
//do a basic call to verify we can see something..
var user = await graphClient.Me.Request().GetAsync();
//provision the email address
await graphClient.Teams[$"{teamId}"].Channels[$"{projectChannel}"].ProvisionEmail()
.Request().PostAsync();
//remove it
await graphClient.Teams[$"{teamId}"].Channels[$"{projectChannel}"].RemoveEmail()
.Request().PostAsync();

Related

Re enter without password after revoke salesforce oauth token

I built a simple app that allows our customers to gather specific information from their Salesforce system. For authentication I used "WebServer Flow", which allows a user to log in to our site with his Salesforce account.
I should of course allow the user to log out of his account. But for some reason, even though I send a Revoke request to Salesforce and get an OK response, when the user redirected again to the Salesforce login page, it automatically logs in to the previous account without re-entering details.
this is the logout action in my backend,
public async Task<ContentResult> LogOutFromSalseforce(string code)
{
AuthenticationClient auth;
bool hasAuth = AuthSessionWrapper.AuthDic.TryGetValue(code, out auth);
if (!hasAuth) return Content(JsonConvert.SerializeObject(new { error = "session expired" }), "application/json");
var url = auth.InstanceUrl + _revokeEndpointUrl;
var cl = new HttpClient();
var res = await cl.PostAsync(url, new FormUrlEncodedContent(new[] { new KeyValuePair<string, string>("token", auth.RefreshToken) }));
AuthSessionWrapper.AuthDic.Remove(code);
return Content(JsonConvert.SerializeObject(new { success = res.StatusCode == HttpStatusCode.OK }), "application/json");
}
And after call from client to this action he redirected to our login page.
I found that even if i call to this revoke endpoint from client it's not work.
only if the user enter in another tab to Salesforce and click logout there, he need to re enter his details to login again to our site.
What I'm doing wrong?
If someone get into the same problem, I solved it with add "&prompt=login" to the login redirect url.

how to use graph api / sdk with AD B2C

I am trying to simply create a user using Graph API sdk against my AD B2C tenant but I keep running into issues. I am following the documentation here: https://learn.microsoft.com/en-us/graph/api/user-post-users?view=graph-rest-1.0&tabs=csharp
The first error I received was that “the domain portion of the userPrincipalName property is invalid. You must use one of the verified domain names in your organization”. After looking around, I found this document that states that the CreationType property must be set to "LocalAccount". When I tried that, I got the error that “one or more properties contains invalid values.”
The error doesn't give any details as to which property is invalid! Can someone at Microsoft please point me to an appropriate document of how to get this working? It seems that there might be some confusion in the documentation where the API is possibly targeting AD as opposed to AD B2C. But I do not have an AD tenant, just an AD B2C tenant, and that's what I am targeting. Again, I am using the latest version of the SDK.
I was able to figure out the issue. For AD B2C, I am supposed to attach an ObjectIdentity to the User object I am passing to be created.
Below is the code:
var identity = new ObjectIdentity
{
Issuer = Globals.Tenant,
IssuerAssignedId = email,
SignInType = "emailAddress"
};
var graphClient = GetGraphServiceClient();
var user = new User
{
DisplayName = fullName,
PasswordProfile = new PasswordProfile
{
Password = password,
ForceChangePasswordNextSignIn = forceChangePasswordSignIn
},
PasswordPolicies = "DisablePasswordExpiration",
AccountEnabled = enabled,
CreationType = "LocalAccount",
Identities = new ObjectIdentity[] { identity }
};
var userInfo = await graphClient.Users.Request().AddAsync(user);
return userInfo;

Twilio configuration Profile SID

I am using the Twilio Video API. In my node.js I used this code,
var grant = new VideoGrant();
It requires configurationProfileSid but I can't find docs on how to get it?
I think it is a capability token.
But how can I get it using twilio node js?
Or is there any other way to get it?
Twilio developer evangelist here.
Configuration Profiles used to be required, but have been deprecated. So you no longer need the configurationProfileSid. You can give access to particular rooms though.
Here's an example Node.js application that generates access tokens for a Video application. The important part is the route that generates the token:
app.get('/', function(request, response) {
// Create an access token which we will sign and return to the client,
// containing the grant we just created
var token = new AccessToken(
process.env.TWILIO_ACCOUNT_SID,
process.env.TWILIO_API_KEY,
process.env.TWILIO_API_SECRET
);
// Assign identity to the token
token.identity = request.query.identity || 'identity';
// Grant the access token Twilio Video capabilities
var grant = new VideoGrant();
grant.room = request.query.room;
token.addGrant(grant);
// Serialize the token to a JWT string
response.send(token.toJwt());
});
This documentation on access tokens should help too.

Automatic Update to Microsoft Graph API Subscription

I have created webhook project with Microsoft Graph API to monitor Office 365 inbox.
I made a UpdateSubscription action method which renews it for 3 days only as according to the documentation provide on https://graph.microsoft.io/en-us/docs/api-reference/v1.0/resources/subscription
Below is the code snippet of how I'am facilitating the HTTP request to update the subscription
AuthenticationResult authResult = await AuthHelper.GetAccessTokenAsync();
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authResult.AccessToken);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// Build the request.
string subscriptionsEndpoint = "https://graph.microsoft.com/v1.0/subscriptions/"+id;
var method = new HttpMethod("PATCH");
HttpRequestMessage request = new HttpRequestMessage(method, subscriptionsEndpoint);
//get the current time
var subscription = new Subscription
{
//Id = id,
ExpirationDateTime = DateTime.UtcNow + new TimeSpan(0, 0, 4230, 0)
};
Is there a way to auto update without the user pressing the button to 'update'?
since the authorization-headers requires AuthResult.accessToken which will require the user to sign in to Office365 account.
Please advice
An option available to you is the service or daemon approach (https://graph.microsoft.io/en-us/docs/authorization/app_only). Instead of authenticating with a logged-in user you're able to renew the subscription at the application level using a Bearer token which is in turn generated by the CLIENT_SECRET from Azure AD.
I don't think storing tokens in the database is the right approach here. My understanding is that security tokens are never appropriate for a database.
In fact, I don't quite understand the need to have the user log in at all here, unless there are parts to the program that you didn't mention. A service like the one I mentioned can monitor a mailbox without a user being there, or else if the program requires the user to be there, there really isn't an issue of lost credentials.
You can use this approach to fetch accesstoken from azure using grant_type a password. PLease find the below screenshot.

Error:”invalid_grant”, Description:””, Uri:”” while using service account from my local machine

I got below error while using service account from my local machine
Error:
invalid_grant”, Description:””, Uri:””.
see code below -
string[] scopes = new string[] {
AnalyticsService.Scope.Analytics
}; // view and manage your Google Analytics data
var keyFilePath = #
"c:\xxxxxxx.p12"; // Downloaded from https://console.developers.google.com
var serviceAccountEmail = "xxxxx#developer.gserviceaccount.com"; // found https://console.developers.google.com
//loading the Key file
var certificate = new X509Certificate2(keyFilePath, "notasecret", X509KeyStorageFlags.Exportable);
var credential = new ServiceAccountCredential(new ServiceAccountCredential.Initializer(serviceAccountEmail) {
Scopes = scopes
}.FromCertificate(certificate));
var service = new AnalyticsService(new BaseClientService.Initializer() {
HttpClientInitializer = credential,
ApplicationName = "Analytics API Sample",
});
string profileId = "xxxxxx";
DataResource.RealtimeResource.GetRequest request = service.Data.Realtime.Get(String.Format("ga:{0}", profileId), "rt:activeUsers");
RealtimeData feed = request.Execute();
invalid_grant has two common causes.
Your server’s clock is not in sync with NTP. (Solution: check the server time if its incorrect fix it. )
The refresh token limit has been exceeded. (Solution: Nothing you can do they cant have more refresh tokens in use)
Applications can request multiple refresh tokens. For example, this is useful in situations where a user wants to install an application on multiple machines. In this case, two refresh tokens are required, one for each installation. When the number of refresh tokens exceeds the limit, older tokens become invalid. If the application attempts to use an invalidated refresh token, an invalid_grant error response is returned. The limit for each unique pair of OAuth 2.0 client and is 25 refresh tokens (note that this limit is subject to change). If the application continues to request refresh tokens for the same Client/Account pair, once the 26th token is issued, the 1st refresh token that was previously issued will become invalid. The 27th requested refresh token would invalidate the 2nd previously issued token and so on.
I have also read of a third which is if you don't include access_type=offline in your request. I have never had an issue with this one myself

Resources