AcquireTokenAsync works normally without valid cilent secret - microsoft-graph-api

I can get the AccessToken to use with MS Graph using the code below
var credentials = new ClientCredential(accessRequest.ClientId, accessRequest.ClientSecret);
var authContext = new AuthenticationContext($"{accessRequest.Authoriy}/{accessRequest.Domain}/");
var result = await authContext.AcquireTokenAsync(accessRequest.Resource, credentials);
var graphAccess = new Library.Service.Implements.GraphCalendarService(result.AccessToken);
var mailsBox = await graphAccess.GetMailboxSettings(accessRequest.User);
The weird thing here is the value of [accessRequest.ClientSecret] used in first line = "qwerty".
Is this a bug or I need find another way to work with MS Graph(condition: need valid ClientId & ClientSecret)?
Thanks in advance.

Related

How do I access Outlook365 mailbox using impersonation using .NET?

I'm using this code:
var cca = ConfidentialClientApplicationBuilder
.Create(clientId)
.WithClientSecret(clientSecret)
.WithTenantId(tenantId)
.Build();
var ewsScopes = new [] { "https://outlook.office365.com/.default" };
var authResult = await cca.AcquireTokenForClient(ewsScopes).ExecuteAsync(cancellationToken);
var service = new ExchangeService
{
Credentials = new OAuthCredentials(authResult.AccessToken),
Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx"),
ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, "mailbox#user.com"),
TraceListener = new TraceListener(),
TraceEnabled = true,
TraceFlags = TraceFlags.All
};
Folder inbox = Folder.Bind(service, WellKnownFolderName.Inbox);
The code throws a ServiceRequestException (403) on the last line, and trace logs contains the error:
x-ms-diagnostics: 2000008;reason="The token contains not enough scope to make this call.";error_category="invalid_grant"
Do I need to expand the ewsScopes? Or is this because I'm lacking the correct permissions in Azure? Which roles/permissions do I need?
Check the token your using in
Credentials = new OAuthCredentials(authResult.AccessToken),
in jwt.io
What you should see in the roles is
If you don't have that role it means your application registration isn't correct (eg you have added the delegate permission instead of Application permission which is a common mistake).

The given token is invalid error in EWS OAuth authentication when using personal account

I have to get the contacts from Exchange server from any account, so we have used the code from below link.
https://learn.microsoft.com/en-us/exchange/client-developer/exchange-web-services/how-to-authenticate-an-ews-application-by-using-oauth
But it is not working for personal accounts, which is working fine for our organization account. So I have used AadAuthorityAudience property instead of TenantId and changed the scope from EWS.AccessAsUser.All to others. Now authentication got success but getting "The given token is invalid" error while using the token in ExchangeService.
var pcaOptions = new PublicClientApplicationOptions {
ClientId = "77xxxxxxxxxxx92324",
//TenantId = "7887xxxxxxxxxxxxx14",
RedirectUri = "https://login.live.com/oauth20_desktop.srf",
AadAuthorityAudience = AadAuthorityAudience.AzureAdAndPersonalMicrosoftAccount};
var pca = PublicClientApplicationBuilder.CreateWithApplicationOptions(pcaOptions).Build();
//var ewsScopes = new string[] { "https://outlook.office365.com/EWS.AccessAsUser.All" };
var ewsScopes = new string[] { "User.Read", "Contacts.ReadWrite.Shared" };
var authResult = await pca.AcquireTokenInteractive(ewsScopes).ExecuteAsync();
var ewsClient = new ExchangeService();
ewsClient.Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx");
//ewsClient.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, "araj#concord.net");
ewsClient.Credentials = new OAuthCredentials(authResult.AccessToken);
// Make an EWS call
var folders = ewsClient.FindFolders(WellKnownFolderName.MsgFolderRoot, new FolderView(10));
What am doing wrong here?
https://outlook.office365.com/EWS.AccessAsUser.All is the right scope to use. The scope is invalid for personal accounts since they're not supported by EWS.

How to use SODA.net and App Token in asp.net-core MVC

As per Socradata.com suggest, I have created both and an Application Token and an Application Key.
When I query using a Soda.net Click using the App Token and username and password like this:
var client = new SodaClient(sodaHost, sodaAppToken, user, pwd);
var soql = new SoqlQuery().Select("draw_date", "winning_numbers", "mega_ball", "multiplier").Where("draw_date > '2018-01-01'").Order(SoqlOrderDirection.DESC, "draw_date");
var dataset = client.GetResource<MyClass>(soda4x4);
var results = dataset.Query<MyClass>(soql);
Or when query using the App Token and App Key like this:
var client = new SodaClient(sodaHost, sodaAppToken, keyId, keySecret);
var soql = new SoqlQuery().Select("draw_date", "winning_numbers", "mega_ball", "multiplier").Where("draw_date > '2018-01-01'").Order(SoqlOrderDirection.DESC, "draw_date");
var dataset = client.GetResource<MyClass>(soda4x4);
var results = dataset.Query<MyClass>(soql);
I get the following error:
System.ArgumentOutOfRangeException
HResult=0x80131502
Message=The provided resourceId is not a valid Socrata (4x4) resource identifier.
Parameter name: resourceId
Source=SODA
StackTrace:
at SODA.SodaClient.Query[TRow](SoqlQuery soqlQuery, String resourceId)
at SODA.Resource1.Query[T](SoqlQuery soqlQuery)
at NumPicker.Controllers.HomeController.MegaMillions() in C:\Users\ka8kgj\Desktop\NumPicker\NumPicker\Controllers\HomeController.cs:line 45
at Microsoft.Extensions.Internal.ObjectMethodExecutor.Execute(Object target, Object[] parameters)
at Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.SyncActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeActionMethodAsync>d__12.MoveNext()
However, when I query anonymously with this client. No error. All is well.
var client = new SodaClient(sodaHost);
var soql = new SoqlQuery().Select("draw_date", "winning_numbers", "mega_ball", "multiplier").Where("draw_date > '2018-01-01'").Order(SoqlOrderDirection.DESC, "draw_date");
var dataset = client.GetResource<MyClass>(soda4x4);
var results = dataset.Query<MyClass>(soql);
Obviously I can not see an issue with the code. Can someone point out what I am missing?
Ok, Here is the answer. It is most embarrassing but I will take the humiliation so that others may not have too..
When you create the app-token on the SOCRATA web site. You get a Key / Secrete pair.
When passing the app-token, It is the KEY that should be passed. NOT THE SECRETE !

Uploading a x509 cert to Application Manifest on Azure ADD or Microsoft Registration Portal

Sorry for the multiple post about the same issue!
I'm trying to upload a self signed sertificate to application manifest created on Microsoft Registration Portal but I have some issues which I don't completly understand why, According to this answer, it's very much possible to upload the certificate using DELEGATED PERMISSIONS however I don't see the reason why I can't use Application Permissions since I only need the AccessToken and I get that with the client_credential grant flow,
Below is the code that I have tried but when retrieving the token with client_credential grant flow, I get stuck att var application = activeDirectoryClient.Applications["ApplicationObjectId"].ExecuteAsync().Result;
and when trying to use the code given to my by Tom Sung in the previous post, the applications exits with error "must have client_credentil or client_assertion in request body"
this is the code that I have tried:
private static async Task<string> GetAppTokenAsync(string graphResourceId, string tenantId, string clientId, string userId)
{
string aadInstance = "https://login.microsoftonline.com/" + tenantId + "/oauth2/token";
var clientCredential = new ClientCredential(clientId, clientSecret);
AuthenticationContext authenticationContextt =
new AuthenticationContext($"https://login.microsoftonline.com/{tenantId}/oauth2/token");
AuthenticationResult result =
await authenticationContextt.AcquireTokenAsync(graphResourceId,
clientCredential);
//token is acquiered and gets stuck
var e = result.AccessToken;
//Tom Suns code
IPlatformParameters parameters = new PlatformParameters(PromptBehavior.SelectAccount);
AuthenticationContext authenticationContext = new AuthenticationContext(aadInstance);
var authenticationResult = await authenticationContext.AcquireTokenAsync(graphResourceId, clientId, new Uri("http://localhost"), parameters, new UserIdentifier(userId, UserIdentifierType.UniqueId));
//exits with error
return authenticationResult.AccessToken;
}
try
{
var graphResourceId = "https://graph.windows.net";
var userId = "****";
//used to test if token is acquired
//var tokennn = await GetAppTokenAsync(graphResourceId, tenantID, ClientId, userId);
var servicePointUri = new Uri(graphResourceId);
var serviceRoot = new Uri(servicePointUri, tenant);
var activeDirectoryClient = new ActiveDirectoryClient(serviceRoot, async () => await GetAppTokenAsync(graphResourceId, tenantID, ClientId, userId));
AsymmetricKeyParameter myCAprivateKey = null;
//generate a root CA cert and obtain the privateKey
X509Certificate2 MyRootCAcert = CreateCertificateAuthorityCertificate("CN=OutlookIntegration", out myCAprivateKey);
//add CA cert to store
addCertToStore(MyRootCAcert, StoreName.Root, StoreLocation.LocalMachine);
var expirationDate = DateTime.Parse(MyRootCAcert.GetExpirationDateString()).ToUniversalTime();
var startDate = DateTime.Parse(MyRootCAcert.GetEffectiveDateString()).ToUniversalTime();
var binCert = MyRootCAcert.GetRawCertData();
var keyCredential = new KeyCredential
{
CustomKeyIdentifier = MyRootCAcert.GetCertHash(),
EndDate = expirationDate,
KeyId = Guid.NewGuid(),
StartDate = startDate,
Type = "AsymmetricX509Cert",
Usage = "Verify",
Value = binCert
};
//gets stuck here when using clientsecret grant type
var application = activeDirectoryClient.Applications["ApplicationObjectId"].ExecuteAsync().Result;
application.KeyCredentials.Add(keyCredential);
application.UpdateAsync().Wait();
}
catch (Exception exception)
{
Console.WriteLine(exception);
throw;
}
I am now completly stuck, Anyone have any idea why it doesn't work with Application Permissions or why it gets stuck at var application = activeDirectoryClient.Applications["ApplicationObjectId"].ExecuteAsync().Result;
Edit 1
is it because I have my app as a web app/API that uses username and password to authenticate?
Based on my test if we want to change the keyCredential, DELEGATED PERMISSIONS is required.
If we want to update Azure AD application other properties, we could use Application Permissions.
Reference:
Azure Active Directory developer glossary
"Delegated" permissions, which specify scope-based access using delegated authorization from the signed-in resource owner, are presented to the resource at run-time as "scp" claims in the client's access token.
"Application" permissions, which specify role-based access using the client application's credentials/identity, are presented to the resource at run-time as "roles" claims in the client's access token.

Upload file on Google drive

I am trying to upload an image on google drive using webapi. I copied the following chunk from Google drive doc but I am getting an error.
Here is the code:
var clientSecret = ConfigurationManager.AppSettings["GoogleDriveClientSecret"];
var credential = GoogleWebAuthorizationBroker.AuthorizeAsync(new ClientSecrets { ClientId = clientId, ClientSecret = clientSecret },
scopes, Environment.UserName, CancellationToken.None).Result;
var service = new DriveService(new BaseClientService.Initializer() { HttpClientInitializer = credential });
var folderId = "0B2bBiMQICgHCMlp6OUxuSHNaZFU";
var fileMetadata = new File()
{
Name = "photo.jpg",
Parents = new List<string>
{
folderId
}
};
FilesResource.CreateMediaUpload request;
using (var stream = new System.IO.FileStream("files/photo.jpg",
System.IO.FileMode.Open))
{
request = service.Files.Create(
fileMetadata, stream, "image/jpeg");
request.Fields = "id";
request.Upload();
}
var file = request.ResponseBody;
Now I am getting 2 errors in this code. First "Cannot resolve symbol Upload" at request.Upload() and second "Cannot resolve symbol ResponseBody" at request.ResponseBody
Any help?
You may refer with this related thread. The adding the attribute Inherits="Library.Account.RootVerifyUsers". Based from this reference, Visual Studio can often get confused about things like this. It is recommended to close Visual Studio and reopen it. Also, closing all open instances of VS may be required.

Resources