I'm implementing Dropbox access into my .NET application
I have a question about the token system by OAuth 2 from Dropbox.
The steps I followed to successfully getting data from Dropbox
ClientSecret and ClientId are given ofc
1. Authorize: by calling https://www.dropbox.com/1/oauth2/authorize
2. Verify the code by Request.QueryString("code")
3. Getting Account info with the response see below:
Getting Account info
var client = new HttpClient()
{
BaseAddress = new Uri("https://api.dropbox.com")
};
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var response = await client.GetAsync("/1/account/info");
var AccountData = JsonConvert.DeserializeObject<DropBoxAccountData>(await response.Content.ReadAsStringAsync());
//Note: DropBoxAccountData is my custom class.
// The Token is also given don't show the code just the querystring["code"]
// that dropbox return by youre redirect_uri
Everything works fine so far.
The first step every time a user access my webpage it needs to be verified by his/her Dropbox account to allow permission from my Dropbox app.
The second time it needs to be know by the application using MSSQL Database or just session for example.
But it looks like it always expires?
Please is there someone that can point me into the right direction.
Once you have the access token ("token" in your code above), you just need to save it. It sounds like you're building a web app, so yes, you would typically store this in the user's session or perhaps associated with the user in a database, if you have such a thing.
Related
there
I want to use JIRA API to access data from my company's JIRA instance. The steps of login process on internet browser are:
Type https://mycompanyname.atlassian.net
Direct to login page.
Type my company email address
It re-directly to Microsoft authentication page, click "Continue".
Type password of my Azure AD domain account.
Select a method to verify my identify (I select way of verifying code sent to my bind mobile)
Bingo!
My questions are:
1.How can I finish above steps by C# code?
2.Does my application need the mobile text code verification for every instance?
FYI:
I want to put my application on Azure function as a timer trigger to run some data from JIRA. However, I get stuck at first step-authentication.
I do not know if you have already solved your issue. But from an azure function there is a few steps you will need to take.
In Azure use Managed Identity, you will need this for function to get some details you will save into Keyvault
Have a Keyvault ready cause you gonna need it to get some secrets out of it
Create your Function app and install Atlassian.SDK - can see documentation here
In the dependency injection of your function call
var config = new ConfigurationBuilder()
.AddAzureKeyVault(secretClient, new KeyVaultSecretManager())
.AddEnvironmentVariables()
.Build();
container.Register(p => Options.Create(config.Get<ConfigDetailsModel>()))
.SingleInstance();
In your Jira service use the following to signin
public JiraService(IOptions<ConfigDetailsModel> config)
{
_config = config.Value;
}
var jira = Jira.CreateRestClient(_config.JiraUri, _config.JiraUserName, _config.JiraApiKey);
var result = await jira.Projects.GetProjectsAsync();
Go to https://id.atlassian.com/manage-profile/security/api-tokens and create an API key for your password as plaintext passwords are not supported anymore by Jira.
Save your username, password and url into keyvault, make password expire at some point.
This should work. Unfortunately the OAUTH way, more secure than the basic way is not really geared towards system-to-system way, well not that I could find, as it requires a user input to allow verification code. If you do not mind moving the flow out of function and into a user flow with OAuth then best article I found is here, but you need to copy additional things from his github to get it to work. I got this flow working in Blazor, and tried to get it to work in my Servicebus triggered function.
The only way I could get the Jira stuff to work in function for service-to-service was to use basic Auth either via the Atlassian.SDK or Httpclient
Note SDK makes life somewhat easier than writing own http client stuff
var client = new HttpClient
{
BaseAddress = new Uri(_config.JiraUri)
};
client.DefaultRequestHeaders.Accept.Clear();
var authenticationString = $"{_config.JiraUSerName}:{_config.JiraApiKey}";
var base64EncodedAuthenticationString = Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(authenticationString));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", base64EncodedAuthenticationString);
var project = await client.GetAsync($"rest/agile/1.0/epic/{projectId}");
var content = await project .Content.ReadAsStringAsync();
UPDATE
When you create an API key in Jira for use in code, know that the API key in JIRA is tied to the person who created it.
It should be an Admin account
Create a global break glass account to manage this, you do not want an apikey tied to a user that might leave in a few months
This break glass account should belong to your DevOps team and no one else who can exploit this api key
I am using Microsoft.Identity.Claim library to conenct to azure and authenticate user.
My first idea was to use AcquireTokenByIntegratedWindowsAuth method but that requires few days until network administrator people investigate how to enable single sign-in option and change that user are now "federated" and not "managed. So I now switched to AcquireTokenInteractive method because chances are that ure will be logged in, so he will just need to choose account from automatically opened browser and that's it. No big deal.
And this works:
string clientId = "xxx";
var tenantId = "yyy";
string[] scopes = new string[] { "User.Read", "User.ReadBasic.All"};
AuthenticationResult result;
var app = PublicClientApplicationBuilder.Create(clientId)
.WithRedirectUri("http://localhost")
.WithAuthority(AzureCloudInstance.AzurePublic, tenantId).Build();
try
{
result = await app.AcquireTokenInteractive(scopes)
.ExecuteAsync();
}
catch (MsalUiRequiredException) //see all possibl exceptions!
{
However, I don't receive claims inside token.
My idea is to send this token to server, then validate it, and if sucessfull create user in database and then use my own authenication mechanism I use for other users (that are not part of domain, completely separate user).
But I don't want all users from domain have access to this app.
So I would like to get claims, roles...
How to get claims, using this or any other lib given user email, or some other unique data?
Here I summarize all of the steps you may need to follow:
1. You need to register a app in azure ad for your service app, you can refer to this document
2. Then you need to register another app in ad as the client app, you can follow the steps in this document
3. After that, you need to do the steps in this document which I already provided in comments. Do it in the service app but not client app.
4. Then you can get the access token with your code and check the claim roles. Please note, do not add microsoft graph permissions into scopes in your code. You need to add api://<the client id of the registered app for service app>/.default into scopes.
5. Now you can find the claim roles in your access token.
I need to create a webservice which will accept a file from a user, parse the file for data, assemble a collection of files stored on Sharepoint, and the return a zip file containing those files to the user.
The user may not have direct access to Sharepoint and in the future there might not even be a human user involved as the file may be pulled automatically from another system on a timer.
I am creating the solution in C# and am struggling to create a client which can successfully authenticate against Sharepoint.
Currently, I am trying to use the CSOM Authentication Manager in the Microsoft documentation, but using the Visual Studio debugger, I observe a failure in this method:
private async Task<string> AcquireTokenAsync(Uri resourceUri, string username, string password)
{
string resource = $"{resourceUri.Scheme}://{resourceUri.DnsSafeHost}";
var clientId = defaultAADAppId;
var body = $"resource={resource}&client_id={clientId}&grant_type=password&username={HttpUtility.UrlEncode(username)}&password={HttpUtility.UrlEncode(password)}";
using (var stringContent = new StringContent(body, Encoding.UTF8, "application/x-www-form-urlencoded"))
{
var result = await httpClient.PostAsync(tokenEndpoint, stringContent).ContinueWith((response) =>
{
return response.Result.Content.ReadAsStringAsync().Result;
}).ConfigureAwait(false);
var tokenResult = JsonSerializer.Deserialize<JsonElement>(result);
var token = tokenResult.GetProperty("access_token").GetString();
return token;
}
}
The value of result is:
"{"error":"unauthorized_client","error_description":"AADSTS700016: Application with identifier '986002f6-c3f6-43ab-913e-78cca185c392' was not found in the directory 'enpal.de'. This can happen if the application has not been installed by the administrator of the tenant or consented to by any user in the tenant. You may have sent your authentication request to the wrong tenant.\r\nTrace ID: d3b47a0b-54bc-40fd-a731-b99732326200\r\nCorrelation ID: 158621cc-3052-4c7b-9532-e2bab5c3cc09\r\nTimestamp: 2020-11-18 13:46:39Z","error_codes":[700016],"timestamp":"2020-11-18 13:46:39Z","trace_id":"d3b47a0b-54bc-40fd-a731-b99732326200","correlation_id":"158621cc-3052-4c7b-9532-e2bab5c3cc09","error_uri":"https://login.microsoftonline.com/error?code=700016"}"
The resourceUri, username, and password values correctly correspond to the values I would directly use to log into the website. My administrator has assured me the user is an admin of the site and therefore should have all the possible permissions it should need to do anything, including connect.
Does anyone know how to make this work?
Or know a different solution which is more likely to work?
Or know of anything which must be configured on the SharePoint side to allow this solution to work?
It looks like you took the code sample from the Microsoft website and skipped on reading an important section: Configuring an application in Azure AD ;)
At the moment, you are trying to connect to your tenant as an app with an id of '986002f6-c3f6-43ab-913e-78cca185c392', which is a placeholder from the code sample. Register your app in your tenant, and insert the proper app id in your defaultAADAppId constant.
I'm trying to read the user's data from Azure Active Directory via Microsofts' Graph API. Using the Graph Explorer I'm able to get all users but using a stand alone application I end up with an "unauthorized" response after receiving a token. I'm clearly missing some steps but it isn't obvious to me what steps that would be. Any insight would be appreciated
The code below is based off a MSFT sample:
// config values
// authority = "https://login.microsoftonline.com/{ TENANT ID }/oauth2/"
// resource uri = "https:// APP NAME .azurewebsites.net";
// graph uri = https://graph.windows.net/TENANT ID/ also tried https://graph.windows.net/v1.0/
// short form
public async void GetUsers( ADConfiguration config )
{
_authContext = new AuthenticationContext(config.GetAuthority());
_clientCredential = new ClientCredential(config.ClientId, config.ClientSecret);
AuthenticationResult result = null;
// obtain the token, this part is still successful
result = await _authContext.AcquireTokenAsync(config.ResourceUri, _clientCredential );
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);
string address = config.GetGraphiUri() + "users?api-version=1.6";
// this response is always unauthorized
HttpResponseMessage response = await _httpClient.GetAsync(address);
}
In addition to answer your new problem . From you code , you are acquiring token using client credential flow. In the client credentials flow, permissions are granted directly to the application itself.
Since you are using Azure AD Graph API , you need to add application permission :
In the Azure portal, choose your application, click on Settings
In the Settings menu, choose the Required permissions section ,select Windows Azure Active Directory(Azure ad graph api) , add related application permissions your app requires .
Inside your app's blade, hit Grant Permissions to do admin consent with your admin's credential .
Your config values seem off:
Authority should be: https://login.microsoftonline.com/{TENANT ID}.
It seems to me that you are trying to use Azure AD Graph API, not Microsoft Graph API.
In that case:
Resource URI should be: https://graph.windows.net/. (MS Graph API is https://graph.microsoft.com/)
im just going to dive straight in and give you a little background on what im trying to do, what i've tried, and the obstacles in my way. so here goes..
MY GOAL
To post to a facebook profile or wall from a desktop application.
The desktop application will be used by individual users who have their own facebook account.
The aim is to create each user their own facebook app and get the app id and app secret.
And then use the app id and app secret in the desktop application ( Saved somewhere in database or config )
to allow the user of the desktop application to post to their profile without having to enter their email address and password to login first
So in summary, 1 facebook app per facebook account.
The app settings will be saved in each users desktop application
Post to their own facebook via their own facebook app without logging in
The main emphasis here being that the user does not have to log in manually via a window or browser.
I have created my facebook app and have set it to live status.. i have also added in all possible permissions and extended permissions in the settings ( Within facebook ) just to make sure i wasnt missing anything.
So I do have my AppID and App secret.. I also have my Client Token which it says to use in place of the app secret for 'auth methods'. I use this to get my access token. I tried the app secret and it doesnt return the access token
MY ATTEMPTS :
C# FACEBOOK SDK
So, i started with and am still trying to use the c# sdk
I can retrieve my access token but cannot post.
I get he below errors all the time with whatever i try... these are just 2 of the many code examples i have tried.
(OAuthException - #2500) An active access token must be used to query information about the current user.
dynamic r = fb.Post("me/feed", new { message = "My seconds wall post using Facebook C# SDK" });
(OAuthException - #190) The client token cannot be used for this API
dynamic r = fb.Post("kevin.maguire.965/feed", new { message = "My second wall post using Facebook C# SDK" });
I read the following extract from the below link which states my access token is an app token and i need a access token for a user or page?
Need Help on OAuthException Code 2500
Error 2500 means you have no access token or an app access token but are trying to access /me/ - 'me' is a placeholder for 'current user or page ID' so won't be valid without an access token for a user or page
So, i have tried to get the userID back using the following Answer ( Facebook C# SDK Get Current User )
var fb = new FacebookClient("access_token");
dynamic result = fb.Get("me", new [] { fields = "id" });
var userId = result.id;
I get the access token which i assume is the app token and not the user token
dynamic result = fb.Get("oauth/access_token", new
{
client_id = this.ApplicationId,
client_secret = this.AppSecret,
grant_type = "client_credentials"
});
fb.AccessToken = result.access_token;
So i have no idea at this moment in time how to post to my profile
I am able to achieve the above using twitter where i can use the secret, token, id etc ... they provide and I can successfully post to my twitter account from a desktop application WITHOUT logging into my twitter account.
Another user has also found it quite easy to post to twitter without any real issues. ( facebook c# sdk getting started )
He also seems to have had success which i have not using the same code - this code was uses in June 2012 so there could have been breaking changes released since
then.
I got the message : (OAuthException - #2500) An active access token must be used to query information about the current user... when i used the sdk.
When i tried to get the access token using a web request and then pass that token to the sdk object to create a facebookclient i got this message
(OAuthException - #190) Invalid OAuth access token signature.
WebRequest request = WebRequest.Create("https://graph.facebook.com/oauth/access_token? grant_type=client_credentials&client_id=999999999999999&client_secret=edefefr8e09r8e08r080r8er0e");
request.Method = "POST";
// Set the ContentType property of the WebRequest.
request.ContentType = "application/x-www-form-urlencoded";
// Get the request stream.
Stream dataStream = request.GetRequestStream();
// Close the Stream object.
dataStream.Close();
// Get the response.
WebResponse response = request.GetResponse();
dataStream = response.GetResponseStream();
// Open the stream using a StreamReader for easy access.
StreamReader reader = new StreamReader(dataStream);
// Read the content.
string accesstoken = reader.ReadToEnd();
MessageBox.Show("accesstoken")
// Clean up the streams.
reader.Close();
dataStream.Close();
response.Close();
var fb = new FacebookClient(accesstoken);
dynamic parameters = new ExpandoObject();
parameters.message = "test";
dynamic result = fb.Post("me/feed", parameters);
var id = result.id;
Obviously in the code above i changed the id and secret to dummy values.
So basically folks...the above links and above code are only a pinch of what I have tried to date in the last few days... i've basically ran out of options and am missing something here which could be averting my attention easily.. or maybe not :) i dont know.
If any one would even have a simple windows form, or wpf window application example using the c# sdk or using restsharp or just using WebRequest object with 'POST' method then I would be eternally greatful.
Just to iterate again that it is a desktop application and not ASP.net .
Many thanks folks for your attention and time.
From what I can see you are supplying an incorrect access token. Since you haven't provided the code with regards to obtaining the access token, may I suggest you take a look at this link which explains how to build a Facebook application, including obtaining an access token via a WebBrowser control.
EDIT: You are supplying the app access token but are trying to post as a user. For this operation you need a user access token which you can obtain by following the steps in the link above.