I'm struggling with a simple Task, that gets new E-Mails in specific Folders in Exchange Online, sets "Processed"-Category and then stores the E-Mail.
Firstly, I create App permissions like that:
var app = ConfidentialClientApplicationBuilder.Create(_appConfig.ClientId)
.WithAuthority(AzureCloudInstance.AzurePublic,
_appConfig.Tenant)
.WithClientSecret(_appConfig.ClientSecret)
.Build();
AuthenticationResult authResultresult = null;
var ewsScopes = new[] {"https://outlook.office.com/.default"};
authResultresult = await app.AcquireTokenForClient(ewsScopes)
.ExecuteAsync();
then I create Exchange-Client and use created Oauth-Token to authorize:
var result = new ExchangeService(ExchangeVersion.Exchange2013_SP1);
result.KeepAlive = false;
result.DateTimePrecision = DateTimePrecision.Milliseconds;
result.Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx");
result.UseDefaultCredentials = false;
var authResultresult = await CreateAppPermissions(_appConfig);
result.Credentials = new OAuthCredentials(authResultresult.AccessToken);
after that I impersonate SMTP-User with my mainSMTP account
result.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, _appConfig.SMTPMailAccount);
after that I use this Code to retrieve an Email using known Id, add for it new Category and update the item like this:
var itemsToStore = result.BindToItems(new []{newItemId}, props);
foreach (var itemToStore in itemsToStore)
{
itemToStore.Item.Categories.Add("Processed");
itemToStore.Item.Update(ConflictResolutionMode.AlwaysOverwrite, true);
}
This code has previously produced “Access is denied. Check credentials and try again., Cannot save changes made to an item to store." - Exception on Item.Update. After a research I have found this :
Office 365 API ErrorAccessDenied (Access is denied. Check credentials and try again.)
and followed the proposed solution by removing "Have full access to a users mailbox"- checkbox flag.
After that I'm getting 401 unauthorized, when I'm calling BindToItems.
Was it a step backwards to remove the checkbox?
RESOLVED:
Found the solution for 401:
since I'm using EWS a.k.a. older API called Exchange Web Services it was a mistake to remove the checkbox.
the reason for “Access is denied. Check credentials and try again., Cannot save changes made to an item to store." was that impersonated user didn't have rights to change someones elses emails
Related
Im trying to programatically create a WorkItem (issue) in AzureDevOps.
However I cannot get the authentication to work.
Im simply trying to migrate from the deprecated SOAP API where we weren't required to use PATs.
So I hope it is still possible to use authentication that does not require the user to put his PAT somewhere.
Our AD is synchronized with Azure.
This is what I have tried:
var appBuilder = PublicClientApplicationBuilder.Create("XXXXXXXXXXXXX");
appBuilder.WithRedirectUri("https://login.microsoftonline.com/common/oauth2/nativeclient");
appBuilder.WithAuthority(AadAuthorityAudience.AzureAdMyOrg);
appBuilder.WithTenantId("XXXXXXXXXXXXXX");
var application = appBuilder.Build();
var authBuilder = application.AcquireTokenByIntegratedWindowsAuth(new[] { "https://app.vssps.visualstudio.com/user_impersonation" });
AuthenticationResult token = authBuilder.ExecuteAsync().Result;
var projectUri = new Uri("https://dev.azure.com/XXXXXXX/");
var credentials = new VssCredentials(new WindowsCredential(true), new VssOAuthAccessTokenCredential(token.AccessToken));
var connection = new VssConnection(projectUri, credentials);
var client = connection.GetClient<WorkItemTrackingHttpClient>();
client.CreateWorkItemAsync(...)
Throws the following exception:
Microsoft.VisualStudio.Services.Common.VssUnauthorizedException: "VS30063: Sie sind nicht autorisiert, auf https://dev.azure.com zuzugreifen."
This is is the apps permission
The part i do not understand is, that the token is created succesfully and i can acquire the instance of WorkItemTrackingHttpClient, but the exception only occurs once i try to create the WorkItem.
I'm trying to read all Inbox email items from an Office 365 mailbox using ExchangeService.
For that, I:
Created an app in my AzureAD portal.
Given this app all permissions.
Issues this app an access secret to use in my code.
The code works to the point that I sucessfully get a token, but when trying to get the folder items I get an 403 error:
'The request failed. The remote server returned an error: (403)
Forbidden.'
I get this error from my dev and my prod environments so I'm pretty sure it's not a network or port issue.
Here's my code:
var cca = ConfidentialClientApplicationBuilder
.Create("myApplicationId")
.WithClientSecret("myClientSecret")
.WithTenantId("myTenantId")
.Build();
var ewsScopes = new string[] { "https://outlook.office365.com/.default" };
// This is where I get the token
var authResult = await cca.AcquireTokenForClient(ewsScopes).ExecuteAsync();
var ewsClient = new ExchangeService();
ewsClient.Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx");
ewsClient.Credentials = new OAuthCredentials(authResult.AccessToken);
ewsClient.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, "my#mail.box");
ewsClient.HttpHeaders.Add("X-AnchorMailbox", "my#mail.box");
// This is where I get the 403 error:
var items = ewsClient.FindItems(
new FolderId(WellKnownFolderName.Inbox, new Mailbox("my#mail.box")),
new SearchFilter.SearchFilterCollection(LogicalOperator.And, new SearchFilter[] {}
),
new ItemView(15)
);
403 if its coming back from Office365 sounds like they have either disabled EWS on the Mailbox your trying to access or they have limited the clients that are allowed to connect eg https://learn.microsoft.com/en-us/exchange/client-developer/exchange-web-services/how-to-control-access-to-ews-in-exchange . You could try testing EWS itself using a user account via the EWSeditor https://github.com/dseph/EwsEditor
I am new to the Azure. I had a requirement retrieve the the users from Azure active directory. I am having Delegated Type, and user.Read and users.Readall.
I am able to get the bearer code but I am getting permission denied when it goes to retrieve the users.
I need to write a console application in c#, below is the code I tried .
var app = ConfidentialClientApplicationBuilder.Create(clientID)
.WithClientSecret(Secret)
.WithRedirectUri(URL)
.WithAuthority("https://login.microsoftonline.com/tenantID/oauth2/token")
.Build();
string[] scopes = new string[] { "https://graph.microsoft.com/.default" };
var token = app.AcquireTokenForClient(scopes).ExecuteAsync().Result;
- GraphServiceClient graphClient1 = new
GraphServiceClient("https://graph.microsoft.com/v1.0", new
DelegateAuthenticationProvider(async (requestMessage) =>
{
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("bearer", token.AccessToken);
}));
var users = graphClient1.Users.Request().Top(99).GetAsync();
var organization = graphClient1.Organization.Request().GetAsync().Result;
I am getting below
system.AggregateException: 'One or more errors occurred. (Code: Authorization_RequestDenied
Message: Insufficient privileges to complete the operation.
for the LIne **var organization = graphClient1.Organization.Request().GetAsync().Result;**
Need help on this
Thanks in advance.
Since you are using delegated permissions it requires users to login to use these permisssions.So, https://graph.microsoft.com/.default is not the correct scope and it should be with delegated permission, For example https://graph.microsoft.com/User.Read.All.
Also, you need to use await before the graph request,
var users = await graphClient.Users.Request().Top(99).GetAsync();
Since you are new to Ms Graph please go through a simple console app code sample with helps you to implement easily.
I'm trying to follow the Resource group authenticate service principal to be able to access some resource manager stuff. But when trying to do anything, I get the following error:
SubscriptionNotFound: The subscription 'resourceGroups' could not be found.
Using the C# code in the article to get an access token, and then calling the follow methods:
var dnsClient = new DnsManagementClient(new Microsoft.Azure.TokenCloudCredentials(result.AccessToken));
var zone = dnsClient.Zones.CreateOrUpdate("someresourcegroup", "mydomain.com", new Microsoft.Azure.Management.Dns.Models.ZoneCreateOrUpdateParameters {
IfNoneMatch = "*",
Zone = new Microsoft.Azure.Management.Dns.Models.Zone {
Name = "mydomain.com",
Location = "northeurope"
}
});
Any idea what I'm doing wrong? I've created a service principal as a Contributor, so permissions shouldn't be a problem?
The error message says The subscription 'resourceGroups' could not be found, please try specify your subscriptionid when creating the TokenCloudCredentials object.
var dnsClient = new DnsManagementClient(new Microsoft.Azure.TokenCloudCredentials("your_subscriptionid", result.AccessToken));
Tested from my side and it works.
I'm looking to start an Azure runbook from a c# application which will be hosted on an Azure web app.
I'm using certificate authentication (in an attempt just to test that I can connect and retrieve some data)
Here's my code so far:
var cert = ConfigurationManager.AppSettings["mgmtCertificate"];
var creds = new Microsoft.Azure.CertificateCloudCredentials("<my-sub-id>",
new X509Certificate2(Convert.FromBase64String(cert)));
var client = new Microsoft.Azure.Management.Automation.AutomationManagementClient(creds, new Uri("https://management.core.windows.net/"));
var content = client.Runbooks.List("<resource-group-id>", "<automation-account-name>");
Every time I run this, no matter what certificate I use I get the same error:
An unhandled exception of type 'Hyak.Common.CloudException' occurred in Microsoft.Threading.Tasks.dll
Additional information: ForbiddenError: The server failed to authenticate the request. Verify that the certificate is valid and is associated with this subscription.
I've tried downloading the settings file which contains the automatically generated management certificate you get when you spin up the Azure account... nothing I do will let me talk to any of the Azure subscription
Am I missing something fundamental here?
Edit: some additional info...
So I decided to create an application and use the JWT authentication method.
I've added an application, given the application permissions to the Azure Service Management API and ensured the user is a co-administrator and I still get the same error, even with the token...
const string tenantId = "xx";
const string clientId = "xx";
var context = new AuthenticationContext(string.Format("https://login.windows.net/{0}", tenantId));
var user = "<user>";
var pwd = "<pass>";
var userCred = new UserCredential(user, pwd);
var result = context.AcquireToken("https://management.core.windows.net/", clientId, userCred);
var token = result.CreateAuthorizationHeader().Substring("Bearer ".Length); // Token comes back fine and I can inspect and see that it's valid for 1 hour - all looks ok...
var sub = "<subscription-id>";
var creds = new TokenCloudCredentials(sub, token);
var client = new AutomationManagementClient(creds, new Uri("https://management.core.windows.net/"));
var content = client.Runbooks.List("<resource-group>", "<automation-id>");
I've also tried using other Azure libs (like auth, datacentre etc) and I get the same error:
ForbiddenError: The server failed to authenticate the request. Verify that the certificate is valid and is associated with this subscription.
I'm sure it's just 1 tickbox I need to tick buried somewhere in that monolithic Management Portal but I've followed a few tutorials on how to do this and they all end up with this error...
public async Task StartAzureRunbook()
{
try
{
var subscriptionId = "azure subscription Id";
string base64cer = "****long string here****"; //taken from http://stackoverflow.com/questions/24999518/azure-api-the-server-failed-to-authenticate-the-request
var cert = new X509Certificate2(Convert.FromBase64String(base64cer));
var client = new Microsoft.Azure.Management.Automation.AutomationManagementClient(new CertificateCloudCredentials(subscriptionId, cert));
var ct = new CancellationToken();
var content = await client.Runbooks.ListByNameAsync("MyAutomationAccountName", "MyRunbookName", ct);
var firstOrDefault = content?.Runbooks.FirstOrDefault();
if (firstOrDefault != null)
{
var operation = client.Runbooks.Start("MyAutomationAccountName", new RunbookStartParameters(firstOrDefault.Id));
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
Also in portal:
1) Application is multitenant
2) Permissions to other applications section - Windows Azure Service Manager - Delegated permissions "Access Azure Service Management(preview)"
Ensure that your Management certificate has private key and was not made from the .CER file. The fact that you're not supplying a password when generating the X509Certificate object makes me think you're using public key only
Ensure that your Managemnet's certificate public key (.CER file) has been uploaded to the Azure management portal (legacy version, Management Certificate area)
Use CertificateCloudCredentials and not any other credential type of an object
Ok, stupid really but one of the tutorials I followed suggested installing the prerelease version of the libs.
Installing the preview (0.15.2-preview) has fixed the issue!