CloudContext.Clients.CreateStorageManagementClient not available? - c#

I installed package azure management library 2, and try to call
var certificate = this.GetStoreCertificate();
Microsoft.WindowsAzure.CertificateCloudCredentials credentials = new Microsoft.WindowsAzure.CertificateCloudCredentials("504fb4ef-3a48-4545-b7fc-b1b6cf821f48", certificate);
var storageClient = CloudContext.Clients.CreateStorageManagementClient(credentials);
But this gives me a compile error with CreateStorageManagementClient function is not available.
What else should I install to create a storage account? I found this MSDN article which explains how to create a storage account, but it doesn't use any library at all and just do a http post to a Microsoft web service. I am wondering there must be some api that I can use?
The msdn link

Related

Azure Function Updating user profile using SharePoint Online and CSOM .NET Standard gives access denied

I have Azure Function v3 and I want to update Sharepoint user profile properties with CSOM and .NET standard 2.0 by using global admin account credentials. Reading is working.
var site = new Uri("https://domain-admin.sharepoint.com");
using (var authenticationManager = new AuthenticationManager())
using (var context = authenticationManager.GetContext(site, user, password))
{
var peopleManager = new PeopleManager(context);
var personProperties = peopleManager.GetPropertiesFor(accountName);
context.Load(personProperties, p => p.AccountName, p => p.UserProfileProperties);
await context.ExecuteQueryAsync();
Console.WriteLine(personProperties.UserProfileProperties["FirstName"]); //works
peopleManager.SetSingleValueProfileProperty(personProperties.AccountName, "FirstName", "CSOMvalue");
await context.ExecuteQueryAsync(); //error, access denied
}
Exact Error message: System.Private.CoreLib: Exception while executing function: FunctionName. Microsoft.SharePoint.Client.Runtime: Access denied. You do not have permission to perform this action or access this resource.
AuthenticationManager class is taken from MS docs from here
Im using Microsoft.SharePointOnline.CSOM v16.1.20518.12000 nuget package.
I made .NET Framework 4.7.2 web app and it worked using SharePointOnlineCredentials. But I want to know how to get it working on .NET Standard 2.0.
From my past experience and couple of hours research :
When you use Azure AD Application, you can read through the User Profiles - but not perform CSOM write operation.
reference :
Though the article says it is applicable for using app-only, this behavior has been observed Azure AD Application in general (user + app as well) - hence the reason why you are able to read but however not write.
As mentioned in the article you will have to the Sharepoint App only context and perform a read/write operation.
context = new AuthenticationManager().GetAppOnlyAuthenticatedContext(siteUrl, "[Your Client ID]", "[Your Client Secret]")
Here the authenticationmanager is of the SharepointPNPcoreOnline library.
This article details the same.
If you want the user context while performing the same (not usually required because you re performing at the UPA ) - you can create the app accordingly - but really not sure whether the SharepointPNPCOreOnline supports this.

What is the proper way to work with the OneDrive API?

I want to interact with OneDrive in my WinForms application. Sadly, the Azure quick start samples do not include WinForms, just UWD.
The flow on what I have to do is consistent, namely given my Client ID, I have to obtain an Authentication Code. Given the authentication code, I can then obtain an Access Code, which will allow me to interact in a RESTful way with the OneDrive API. My plan is to have the authentication piece go in a .Net Framework Library and the file IO calls will go in another library that has no user interface access, as it will go in a Windows Service. I would pass the Access Token to the service.
AADSTS50059: No tenant-identifying information found in either the request or implied by any provided credentials.
This error corresponds to the following code fragment that I lifted from the sample .Net Core daemon quick start code.
Note: I was playing around with Scopes as I kept receiving scope errors and I saw one article, whose link I should have kept, which stated to use the API and default scope.
public bool GetRestAuthenticationToken(out string tokenAuthentication)
{
tokenAuthentication = null;
try
{
IConfidentialClientApplication app;
app = ConfidentialClientApplicationBuilder.Create(Authenticate.AppClientId)
.WithClientSecret(Authenticate.AppClientSecret)
.WithAuthority(new Uri(#"https://login.microsoftonline.com/common/oauth2/nativeclient"))
.Build();
string scope = $"onedrive.readwrite offline_access";
System.Collections.Generic.List<string> enumScopes = new System.Collections.Generic.List<string>();
enumScopes.Add("api://<GUID>/.default");
//enumScopes.Add(Authenticate.Scopes[1]);
var result = Task.Run(async () => await app.AcquireTokenForClient(enumScopes).ExecuteAsync()).Result;
...
}
...
}
I believe that I have my application configured properly now on Azure, but am not 100% positive.
API Permissions:
Authentication:
Desktop Applications: https://login.microsoftonline.com/common/oauth2/nativeclient
Desktop Applications: https://login.live.com/oauth20_desktop.srf
Implicit Grants: Access tokens & ID tokens
Live SDK support (Yes)
Default client type (Yes)
Others:
I do have a client secret and kept note of all the Overview GUIDs
Microsoft Doc 1
I tried several different URLs, but only the one not commented out works with the fragment above, but throws the referenced error.
//string redirect_uri = #"https://www.myapp.com/auth";
//string redirect_uri = "https://login.live.com/oauth20_desktop.srf";
string url = #"https://login.microsoftonline.com/common/oauth2/nativeclient";
//string url = $"https://login.live.com/oauth20_authorize.srf?client_id={appClientId}&scope={scope}&response_type=code&redirect_uri={redirect_uri}";
//string url = $"https://login.microsoftonline.com/common/oauth2/v2.0/authorize?" +
// $"client_id={Authenticate.AppClientId}&" +
// $"scope={scope}&" +
// $"response_type=token&" +
// $"redirect_uri={redirect_uri}";
The goal is the same, namely to obtain an access token that I can use with RESTful calls to work with files and/or directories on OneDrive, e.g.
System.Net.Http.HttpClient client = new System.Net.Http.HttpClient();
client.GetAsync(...);
You are trying to implement Client credentials grant type to get the access token.
Based on MSAL initialization, Authority is
(Optional) The STS endpoint for user to authenticate. Usually
https://login.microsoftonline.com/{tenant} for public cloud, where
{tenant} is the name of your tenant or your tenant Id.
We assume that your tenant is "myTenent.onmicrosoft.com", then you should set it as https://login.microsoftonline.com/myTenent.onmicrosoft.com here.
I notice that you specify a scope "onedrive.readwrite" in your code. But it's not a valid permission of Microsoft Graph. The default scope of Microsoft Graph is https://graph.microsoft.com/.default.

How to set credentials on AWS SDK on NET Core?

I'm new to AWS SDK and I'm trying to follow the AWS documentation, but gives little to none on what exactly I need to setup.
The official docs tell me to add this to the appsettings.json:
{
"AWS": {
"Profile": "local-test-profile",
"Region": "us-west-2"
}
}
And then create the client:
var options = Configuration.GetAWSOptions();
IAmazonS3 client = options.CreateServiceClient<IAmazonS3>();
This causes an exception to be thrown saying it cannot find the credentials. Where do I put the Api ID and Key? What is this profile?
Please, bear in mind I have no preferences on how to set this up. I'm just trying to follow the official documentation for .NET Core, and their only example doesn't work. The docs seem to imply I should have prior knowledge of many of their terms and settings or that I'm migrating an existing app and already have everything setup.
Can someone please point me to what is missing from this example just to make the API correctly connect to AWS?
Maybe this is too late for you but if you are using docker or have some other environment/setup where it's not possible/easy to use AWS profiles then you can still use environment vars. Eg:
var awsOptions = Configuration.GetAWSOptions();
awsOptions.Credentials = new EnvironmentVariablesAWSCredentials();
services.AddDefaultAWSOptions(awsOptions);
services.AddAWSService<IAmazonS3>();
Then set AWS_ACCESS_KEY_ID & AWS_SECRET_ACCESS_KEY & AWS_REGION in your environment.
It seems that Amazon have made this harder to find in the docs than it needs to be.
Running in AWS for reals is ok because you should be using a role but if your using docker for dev then setting up a profile in the container is a PITA.
The json file is $"appsettings.{env.EnvironmentName}.json", so you should call it appsettings.Development.json and have the environment variable set.
Did you define your"local-test-profile" profile in the AWS credentials file.
Should be in C:\Users\{USERNAME}\.aws\credentials
[local-test-profile]
aws_access_key_id = your_access_key_id
aws_secret_access_key = your_secret_access_key
If you don't want it in the default location, you can set the 'ProfilesLocation' json config file.
This helps to avoid getting credentials from environment using the appsettings for development purpose
var awsOption = Configuration.GetAWSOptions();
awsOption.Credentials = new BasicAWSCredentials(Configuration["AWS:AccessKey"], Configuration["AWS:SecretKey"]);
services.AddDefaultAWSOptions(awsOption);
AWS SDK for .NET uses following order to load credentials:
1. AWSOptions.Credentials property
AWSOptions awsOptions = new AWSOptions
{
Credentials = new BasicAWSCredentials("yourAccessKey", "yourAccessSecret")
};
builder.Services.AddDefaultAWSOptions(awsOptions);
2. AWSOptions.Profile property
AWSOptions awsOptions = new AWSOptions
{
Profile = "custom",
ProfilesLocation = #"c:\temp\credentials"
};
builder.Services.AddDefaultAWSOptions(awsOptions);
If the profile location is not specified, it will look at the default location C:\Users\.aws\credentials.
3. Credential Profile Store Chain
If both AWSOptions.Credentials and AWSOptions.Profile are not supplied or AWSOptions object itself is null. In this case, credential profile name will be loaded from the environment variable AWS_PROFILE.
Profile Name: If there is no such AWS_PROFILE environment variable, then default will be used as a profile name.
Profile Location: C:\Users\.aws\credentials
4. Environment Variables AWS Credentials
If SDK still hasn't got the credentials, then it checks for the following environment variables to load the AWS credentials.
ENVIRONMENT_VARIABLE_ACCESSKEY = "AWS_ACCESS_KEY_ID";
ENVIRONMENT_VARIABLE_SECRETKEY = "AWS_SECRET_ACCESS_KEY";
ENVIRONMENT_VARIABLE_SESSION_TOKEN = "AWS_SESSION_TOKEN";
5. EC2 Instance Profile / ECS Task Profile
Finally, this is the most important place where the SDK looks for the credentials. This would be the best place for the applications that are running in the AWS environment. In this case, SDK loads the AWS credentials from the EC2 instance profile or ECS task role.
I have also written a blog on the same topic, you can checkout that from here - Understanding Credential Loading in AWS SDK for .NET
Same documentation also includes a section for setting up the credentials.
Check it out here http://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/net-dg-config-creds.html
It doesn't give an example of setting up the credentials using the appSettings.json file because they don't think it's the right (secure) way to do it.
Here is from the introduction part of the section about setting up the credentials:
Don't put literal access keys in your application, including the
project's App.config or Web.config file. If you do, you create a risk
of accidentally exposing your credentials if, for example, you upload
the project to a public repository.

Error using AutomationManagementClient with CertificateCloudCredentials

I'm trying to start an azure runbook from a MVC app.
var cert = new X509Certificate2(Convert.FromBase64String(ConfigurationManager.AppSettings["CertBase64String"]));
var creds = new CertificateCloudCredentials(ConfigurationManager.AppSettings["SubscriptionId"], cert);
AutomationManagementClient automationManagementClient = new AutomationManagementClient(creds);
var content = automationManagementClient.Runbooks.GetAsync(<Resource group name>, ConfigurationManager.AppSettings["AutomationAccount"], <Runbook name>)
I get this error:
AuthenticationFailed: Authentication failed. The 'Authorization' header is missing.
I got this code from MSDN but I can't seem to make it work.
(The certificate is the one downloaded from here ).
I tried using TokenCloudCredentials from a Console app and that seems to work fine but I'm not sure if I can use those in the MVC app.
Any ideas how I should use AutomationManagementClient with certificate credentials? Or how to use TokenCloudCredentials in the web app?
The Automation SDK you are attempting to use uses Azure Resource Manager APIs, which do not support management certificate-based authentication. You will need to authenticate via TokenCloudCredentials. The documentation that shows management certificate support is incorrect and we will update it shortly.

Dropbox - Migrating oauth1 to oauth2 using token_from_oauth1

I have been using Dropbox via the Sharpbox toolkit for a while. It's based on oAuth1, so I have a database full of oAuth1 access tokens for my users.
I'd like to convert to the new Dropbox API, which is based on oAuth2. I see that there is a "token_from_oauth1" endpoint in Dropbox's v1 spec (reference here), but I'm not figuring out how to successfully connect to this endpoint to upgrade a user's existing token. (I'm using C#/.NET).
Can anybody point me to some sample code that shows how to create a properly authenticated call to perform this operation? I think the problem is in trying to correctly authenticate/sign the request. (All of my existing dropbox calls are done by the Sharpbox library, so I can't see how it does the authentication).
Thanks!
You can get this using a simple rest client (Like RestSharp) and doing a call like this
I'm currently doing this in a xamarin app, i use the xamarin dropbox core api to login, and get the oauth_token, oauth_consumer_key and the oauth_signature. If you managed the oauth1 flow with c# is then easy to get the oauth2 token.
var rclient = new RestSharp.RestClient("https://api.dropboxapi.com/1/");
var rrequest = new RestSharp.RestRequest("oauth2/token_from_oauth1", Method.POST);
rrequest.AddHeader("Authorization", "OAuth oauth_version=\"1.0\", oauth_signature_method=\"PLAINTEXT\"");
rrequest.AddParameter("oauth_consumer_key", store.GetConsumerKey());
rrequest.AddParameter("oauth_token", store.GetAccessToken());
rrequest.AddParameter("oauth_signature", String.Concat(App.DropboxAppSecret, "&", store.GetAccessTokenSecret()));
var rresponse = rclient.Execute(rrequest);
string content = rresponse.Content;
There's a library for Twitter oAuth 1.0 (see http://www.voiceoftech.com/swhitley/?p=681) that actually makes it easy to make oAuth 1.0 authenticated calls. So the code below seems to work pretty well for me:
oAuthTwitter oat = new oAuthTwitter();
oat.Token = <oauth 1.0 token>;
oat.TokenSecret = <oauth 1.0 secret>;
oat.ConsumerKey = <application key>;
oat.ConsumerSecret = <application secret>;
string resultJSON = oat.oAuthWebRequest(oAuthTwitter.Method.POST, "https://api.dropboxapi.com/1/oauth2/token_from_oauth1", null);

Categories