Currently I'm trying to create user activity from uwp application. But every time I encounter this response.
{
"error": {
"code": "AuthenticationError",
"message": "Error authenticating with resource",
"innerError": {
"date": "2022-12-28T09:20:16",
"request-id": "some id",
"client-request-id": "some id"
}
}
}
Here is my c# code example. Request content string was taken from microsoft docs
public sealed class UserActivityProvider : IUserActivityProvider
{
private const string activityId = "SendMessageUserActivity";
private static HttpClient httpClient = new HttpClient();
public UserActivityProvider()
{
}
private async Task<string> GetAccessTokenAsync(Account account)
{
var accessToken = string.Empty;
var publicClientApplication = PublicClientApplicationBuilder.Create(MicrosoftConstants.ClientId)
.WithRedirectUri(MicrosoftConstants.RedirectUri)
.Build();
var scopes = new string[]
{
"UserActivity.ReadWrite.CreatedByApp"
};
AuthenticationResult? authToken = null;
try
{
authToken = await publicClientApplication.AcquireTokenSilent(scopes, account.Email).ExecuteAsync();
}
catch (Exception)
{
authToken = await publicClientApplication.AcquireTokenInteractive(scopes).ExecuteAsync();
}
if (authToken != null)
{
accessToken = authToken.AccessToken;
}
return accessToken;
}
public async Task CreateUserActivityAsync(Account account, CreatingMessageUserActivityParameters userActivityParameters)
{
var accessToken = await GetAccessTokenAsync(account);
if (accessToken != string.Empty)
{
var contentForCreatingActivity = new StringContent("{\r\n \"appActivityId\": \"SendMessageUserActivity\",\r\n \"activitySourceHost\": \"https://www.contoso.com\",\r\n \"userTimezone\": \"Africa/Casablanca\",\r\n \"appDisplayName\": \"Contoso, Ltd.\",\r\n \"activationUrl\": \"https://www.contoso.com/article?id=12345\",\r\n \"contentUrl\": \"https://www.contoso.com/article?id=12345\",\r\n \"fallbackUrl\": \"https://www.contoso.com/article?id=12345\",\r\n \"contentInfo\": {\r\n \"@context\": \"https://schema.org\",\r\n \"@type\": \"Article\",\r\n \"author\": \"Jennifer Booth\",\r\n \"name\": \"How to Tie a Reef Knot\"\r\n },\r\n \"visualElements\": {\r\n \"attribution\": {\r\n \"iconUrl\": \"https://www.contoso.com/icon\",\r\n \"alternateText\": \"Contoso, Ltd.\",\r\n \"addImageQuery\": false\r\n },\r\n \"description\": \"How to Tie a Reef Knot. A step-by-step visual guide to the art of nautical knot-tying.\",\r\n \"backgroundColor\": \"#ff0000\",\r\n \"displayText\": \"Contoso How-To: How to Tie a Reef Knot\",\r\n \"content\": {\r\n \"$schema\": \"https://adaptivecards.io/schemas/adaptive-card.json\",\r\n \"type\": \"AdaptiveCard\",\r\n \"body\": [\r\n {\r\n \"type\": \"TextBlock\",\r\n \"text\": \"Contoso MainPage\"\r\n }\r\n ]\r\n }\r\n }\r\n}", Encoding.UTF8, "application/json");
httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " accessToken);
var response = await httpClient.PutAsync($"https://graph.microsoft.com/beta/me/activities/{activityId}", contentForCreatingActivity);
var stringifiedResponse = await response.Content.ReadAsStringAsync();
}
}
}
And here is also get method for retrieving all activities and it's also return bad request
public async Task<string?> IsUserActivityExistsAsync(Account account)
{
string? resultSubject = null;
var accessToken = await GetAccessTokenAsync(account);
if (accessToken != string.Empty)
{
httpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " accessToken);
var response = await httpClient.GetAsync("https://graph.microsoft.com/v1.0/me/activities");
var stringifiedResponse = await response.Content.ReadAsStringAsync();
}
return resultSubject;
}
All articles referencing that I have to provide correct scope but I took that scope from official microsoft docs and there wouldn't be a mistake.
Response for getting activities
{
"error": {
"code": "UnknownError",
"message": "{\"ErrorCode\":2,\"ErrorMessage\":\"Substrate operation failed. Url: https://substrate.office.com/api/v2.0/users('******(73)')/CurrentCollections('******(10)') Status: Unauthorized. Error Code: invalid_tenant Error Message: The tenant for tenant guid 'tenant' does not exist., SubstrateError: null\"}",
"innerError": {
"date": "2022-12-29T05:44:57",
"request-id": "id",
"client-request-id": "id"
}
}
}
Response for adding activities
{
"error": {
"code": "UnknownError",
"message": "{\"ErrorCode\":35,\"ErrorMessage\":\"General error occurred. Contact product team.\"}",
"innerError": {
"date": "2022-12-29T05:59:02",
"request-id": "id",
"client-request-id": "id"
}
}
}
CodePudding user response:
Please make sure that UserActivity.ReadWrite.CreatedByApp
MS Graph API permissions are assigned to your app in Azure AD as Delegated type (not Application)
UPDATED:
Not sure if you're using correct authentication provider, for delegated type (check options here https://learn.microsoft.com/en-us/graph/sdks/choose-authentication-providers?tabs=CS)
Try to acquire token by updating your code with the following changes
var publicClientApplication = PublicClientApplicationBuilder
.Create(MicrosoftConstants.ClientId)
.WithTenantId("YOUR_TENANT_ID")
.Build();
and
var authToken = await publicClientApplication
.AcquireTokenByIntegratedWindowsAuth(scopes)
.ExecuteAsync()
.Result;
Note: Execute code under user account belonging to organization
CodePudding user response:
As you said you are getting empty data when you decoded the access token in jwt.ms , which means you are doing something wrong while acquiring access token , follow the doc to get token via Interactive provider , and then again check by decoding in jwt.ms .
var scopes = new[] { "User.Read" };
// Multi-tenant apps can use "common",
// single-tenant apps must use the tenant ID from the Azure portal
var tenantId = "common";
// Value from app registration
var clientId = "YOUR_CLIENT_ID";
// using Azure.Identity;
var options = new InteractiveBrowserCredentialOptions
{
TenantId = tenantId,
ClientId = clientId,
AuthorityHost = AzureAuthorityHosts.AzurePublicCloud,
// MUST be http://localhost or http://localhost:PORT
// See https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/System-Browser-on-.Net-Core
RedirectUri = new Uri("http://localhost"),
};
// https://learn.microsoft.com/dotnet/api/azure.identity.interactivebrowsercredential
var interactiveCredential = new InteractiveBrowserCredential(options);
var graphClient = new GraphServiceClient(interactiveCredential, scopes);