Unattended DropBox .net back end access - c#

I want my web server code (invoked from ASP.NET MVC3 site's controller) to be able to save files to Dropbox account.
I have examined two out of three .Net/Dropbox libraries and all of them require a user to "authenticate" via web-redirect to Dropbox to get a token.
Examined libs are Spring.Social.Dropbox and DropNet.
Can this authentication and upload be done via purely .net code without messing with the user's browser? Can the acquired token be saved for later use? This is theoretical question, not about particular implementation.

This is a bit of a complicated subject. As far as I know Dropbox uses OAuth, which is an authentication and authorization protocol.
General process is this:
You create authorization request token
User gets redirected, authenticates and grants permissions to your app.
You trade the request token for an access token
You must save the access token because it is used to perform actions on the users behalf
Access tokens don't usually expire and only stop working if a user revokes your application permissions.
This means the user will have to authenticate and authorize your application at least once so you can get the access token and access token secret.
After that, you are pretty much free to perform actions on the users' behalf based on the permissions granted. You must specify the access token attained by the above-mentioned process in order to perform actions.
In short, get an access token, save it, use it for requests.
Does this clarify it a bit for you?

Related

dropbox-sdk-dotnet: how to get a refresh token and update the access token

I'm using the Dropbox SDK for DotNet, and it is time to support short-lived Access tokens.
My use case is uncommon (web site, 'backend side'). Once the link to DropBox is made, everything should keep working unattended.
In fact, it is OK to never publish the app. Each user creates its own app in their own Dropbox account and stays on Development mode forever.
Until now, the user created the dropbox app, takes note of the App key, App secret and generates an access token directly at https://www.dropbox.com/developers/apps/info/....
With this data, the application was working fine, but Access tokens will soon be short-lived only. I already verified the like to dropbox gets broken after the generated (from www.dropbox.com/developers/apps) Access Token expires.
How can I, using the SDK and having a valid Access token, get a refresh token to be saved and utilized to get a renewed access token?
I couldn't find any way in DropboxClient.cs, DropboxOauth2Helper.cs, not the examples at https://github.com/dropbox/dropbox-sdk-dotnet/tree/main/dropbox-sdk-dotnet/Examples
It is not possible to use an access token to retrieve a refresh token. A refresh token can only be retrieved via the OAuth flow. I recommend reading the OAuth Guide for more information.
The "Generate" button on the app info page on the App Console does not currently offer the ability to generate a refresh token, but I'll pass this along as a feature request. I can't promise if or when that might be implemented though.

Microsoft identity - revoke authorization

I'm developing a .NET application that can send emails on behalf of the user using the Graph API.
Users are prompted to authorize the application; The acquired access token is then used to call the Graph API. The refresh token is used to issue a new access token when the old one expires, as described here: https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow
Couple of questions / observations:
Assume user John authorizes the app to send emails on his behalf. If an administrator removes the app from the azure portal, the access/refresh tokens issued when John authorized the app will still work.
if the access token is still active, it can be used to call the graph api;
if the access token is expired, the refresh token can still be used to request a new access token
Is this behavior intended?
After reading https://learn.microsoft.com/en-us/azure/active-directory/users-groups-roles/users-revoke-access and https://learn.microsoft.com/en-us/powershell/module/azuread/revoke-azureaduserallrefreshtoken?view=azureadps-2.0 it seems that simply removing the app from the user doesn't revoke the tokens.
Assume user John authorizes the app to send emails on his behalf. If John goes to https://myapplications.microsoft.com and removes the app he won't be able to use the refresh token to get a new access token, which is expected.
However, I've noticed that if John reauthorizes the application to perform actions on his behalf, the application won't show up on https://myapplications.microsoft.com anymore. This behavior seems a bit inconsistent. What's the proper way for a user to revoke access to an application?
If the user has granted access to the application, Azure AD will issue an access token and a refresh token for the resource.
The lifetime of the access token is usually about 1 hour. During its lifetime, even if the application is deleted, it is still available, but you will not be able to use the refresh token to obtain the access token again.
If you need to revoke authorization during the lifetime of the access token, please see: here and here.

Allow supporter to sign in as another user

We currently have an Identity server 4 application. Using entity framework core and asp .net identity.
We have a group of supporters who need to be able to access our users accounts in order to help them with issues over the phone. Our users are not able to figure out how to use team viewer. As most of them are mobile and will only have a cellphone at the time.
I know all the security ramifications of allowing other people to sign into your account however there is really no way around this. Our customers have accepted that our supporters can connect to their account when they request it. We trust that our supporters only do this when its requested.
Current solution and its issues
The current hack creates an api endpoint which only our supporters can use as it has been locked down so that only those with supporter permission can use it. They send the users email and we hack create them an access token which is then used by the application (Web version) to act like its the user who is having issues.
This solution was created by my predecessor basically by taking the supporters access token and replacing all of the claims with this supporters id to the users id and returning it to the application. I hate this solution on a number of levels and its very unstable every time i look at this method it breaks. currently its not working because audience clams are incorrect for some reason.
What i want to do
I would really like to do this in a less hack way. So is there a way to sign in a user to the application without it actually being them thats doing the signing in and return an access token?
I have tried doing
await _signInManager.SignInAsync(user, false, null);
But i cant seam to figure out how to get that to return an access token.
What i would really like to do is have the ability for supporters to login to any ones account but do it securely somehow.
The problem with the user account is that it's not bound to one application. So by allowing others to login using the account, you give them also access to other applications. As a workaround you could use 'public' accounts, like engineer_01, engineer_02, etc.
But, this may not be necessary at all. What you really want IMO is to impersonate the user, instead of 'hacking' the account.
One way to do this, is to extend IdentityServer with a custom grant type using extension grants.
How this could work:
A signed-in user, who is allowed to impersonate users for the particular client/resource, requests an access token at the new impersonation endpoint.
The user sends the sub from the user to impersonate to the endpoint, where the user and (combination of ) sub are verified.
When access is granted a new (short-lived) access token is returned which can be used to impersonate the user, without having to know the credentials of the user.
The access token should contain information of the endpoint so it can be determined whether the user is impersonated.
We implemented an impersonation feature that is integrated into the browser-based sign in flow. If a user with permission chooses to sign in as another user then we add additional claims to their IDS4 authentication cookie which then supports issuing extra claims in the resulting token that reflect that it's an impersonation session and who the original actor is.
Navigate to client application
Sign in using whatever credentials
Check if any impersonation permissions exist (how these are defined is entirely up to you)
Prompt for impersonation account selection (or just continue as self)
Sign in as the selected account (with record of original actor)
Redirect to authorize endpoint
Issue tokens and redirect back to client application

Get token for any AAD user

A requirement is set upon me to implement impersonation for developers, of course only for development environment. I was wondering if it is possible to request a token for any AAD user without knowing the password. The flow I would want is:
Developer goes to web application to select a user he wants to impersonate.
The web application checks if the developer is in the AAD.
The web application checks if the developer has the necessary rights to impersonate.
The web application returns a token valid for the user the developer selected.
The developer can use this token to authenticate against the API, and for all intents and purposes is the impersonated user.
Any good alternatives to this approach are also welcome.
No, you cannot impersonate a user like this.
You can acquire an access token if you know their password and they don't have MFA etc. with the Resource Owner Password Credentials grant flow.
But if you want to do it in a better way, you could have the users who you wish to impersonate login to your app.
Acquire an access token + refresh token for them.
Then store the refresh token securely.
Now you can use the refresh token at any time along with your app's client credentials to acquire a token for that user.
Refresh tokens can and do expire though, for example if the user's password is changed.
But this could allow you to implement what you want.

some difficulties in OAuth 2: Should I save authorization code or just access token?

Note: This is not about coding, but about the approach itself.
I'm making a client for a website which uses OAuth 2.. Since this is my first time using oauth 2 I have some problems in understanding the approach. As I know until now:
I should send my access token with every request. To get this access token in the first time I send user to the website and after login I get an authorization code. Then I send this authorization code and my client_id and client_secret to get the access token and finish.
until here every thing is fine. But in the next application execution, I don't know what to do. I don't want to ask user to login every time. But how can I know my access token is still valid?
should I save my authorization code and request a new access token again?
I request a non-expiring access token, but to refresh the access token I should send some refresh_token? What is this? Should I send the old access token as this?
#Eugenio's answer is correct.
To answer your specific questions
But how can I know my access token is still valid?
The access token comes with an expiration time, usually one hour. The other way is to try to use it and catch the 401 status if it's expired.
should I save my authorization code and request a new access token again?
No. The authorization code can only be used once. You can either request a refresh token, save that, and then use that to get subsequent access tokens, or you can repeat the authorization process, which depending on the provider, may or may not require user involvement since the provider will know that the user has previously authorized your app.
I request a non-expiring access token, but to refresh the access token I should send some refresh_token?
There is no such thing as a non-expiring access token. You use a refresh token in order to obtain a new access token.
What is this [refresh token]?
It's a string that your app can pass to the provider to say "hey it's me again. Remember a while ago user xxxxx, granted me, application yyyy (client id), the authority to do aaaa and bbbb (scopes) on his behalf, even when he's not present. Well I'd like to do some now so please can I have an access token".
Should I send the old access token as this?
No. Once an access token has expired it has no use or significance at all.
The access_token you get from the authentication site is good to call their APIs, not your app. You should keep it if you need to call them back eventually in your app.
For example, if your users are authenticating with Facebook, the access_token you get will be good to call Facebook's endpoints.
OAuth2 is in essence an authorization protocol: the user is granting you permission to access his/her information on their behalf.
A commonly used, and useful side effect of this process is to treat these users as "authenticated" because, presumably, you can only get an access_token from a legitimate user.
It is then up to your site to establish a session with them. You would do this exactly as you would if you were authenticating the user yourself, likely after you successfully retrieved the access_token using the code. (or sometimes after retrieving the user profile from the Authorization Server, another common technique).
You can browse a sample that does this on the .NET platform here: https://docs.auth0.com/aspnet-tutorial (this is configured to work with our own OAuth server, but the principles are generic).
The code this sample relies on is available here: https://github.com/auth0/auth0-aspnet

Categories

Resources