How would one go about supporting 3-legged OAuth workflows from a custom command line tool?
I would like to allow the users of my CLI tool to go online, log in, and have the token cached locally, similarly to what heroku login is doing.
You have to go throw the consent screen.
You can do it with electron, here is an example for Github OAuth.
So you write code that open electron on the OAuth endpoint and grab the cookies from electron.
But if you want 3-legged you have to have a server.
so you can either setup a public server that handle the request (defined as the redirect URL for your app), return the access token and catch it from the code that opened electron (if you set it as cookies it will also be cached).
If you don't want a public server, you can set the redirect URL to localhost and open both electron and a local web server.
Related
I have a command-line app that I want to authenticate against AWS Cognito using OAuth2 with access code flow and hosted login UI. For the similar case, Google Cloud docs explicitly recommend using http://localhost:N redirect URI, so that the application can handle the access code after authentication:
This authorization flow is similar to the one used for web server applications. The main difference is that installed apps must open the system browser and supply a local redirect URI to handle responses from Google's authorization server.
However, with Cognito localhost URIs are only allowed/recommended for testing purposes:
One alternative solution would be using an "out-of-browser" URI urn:ietf:wg:oauth:2.0:oob to display the access code in the browser and make the user copy-paste it to the app, but Cognito doesn't seem to support it.
Currently I am leaning towards running a custom OAuth2 callback handler that would only tell the user to copy-paste the access code, but I don't find it really friendly from the Cognito side.
So, the question:
What's the recommended way to authenticate desktop / command-line apps with Cognito with minimal user interference?
What can go wrong if I ignore the Cognito's recommendation about the localhost redirect URI?
LOOPBACK URI
In a desktop app you can use localhost HTTP URLs to receive the authorization response, and that is one valid technique.
The Cognito warning is about using localhost URLs for web app responses, which of course is only suitable for a developer PC.
You can ignore the warning when using loopback desktop apps.
OUT OF BROWSER URI
This was used a few years ago to read an authorization response from a web view and is no longer recommended in OAuth for Native Apps.
PRIVATE URI SCHEME
The second valid rechnique is the option I prefer, since it feels more integrated. It involves receiving the authorization response via a URL of the following form, and registering the scheme with the OS to point to your app:
com.mycompany.mydesktopapp:/callback
RESOURCES OF MINE
If it helps, I have a couple of desktop samples / blog posts that use Cognito. You can run the samples on your PC, to see which you prefer:
Loopback URI
Private URI Scheme
How can I use cURL or Postman to read a web page from behind Azure's AD Application Proxy?
I am trying to better understand how OAuth works in order to create some automation scripts that will need to access a server that we have behind an Application Proxy. Currently I am using a web browser and must sign in to my Microsoft account in order to view a web page hosted by the server. This works fine. Seeing as I am able to accomplish this without difficult using a web browser, it seems like I should also be able to accomplish the same using cURL or Postman.
The app that we have registered is registered as a confidential client (Microsoft's "Web App"). The public client option is disabled. It uses the Implicit Grant type to return an ID Token (The Access Token checkbox is not checked, only the ID Token checkbox). I don't have the ability to create a new client secret nor the ability to enable a public client type.
I have tried several of the different OAuth flows, but they all seem to require a client secret (because we are using the confidential client type), which I do not have access to. How am I able to read the web page through the browser despite not knowing any client secrets? How can I do the same via cURL or Postman?
After being redirected to Microsoft's login page and logging in, Azure saves an access cookie in the browser. You can copy this access cookie and include it as part of a request in Postman. This will allow the request from Postman (or curl or whatever) to get to the service behind the Azure AD Application Proxy.
This is enough for my particular use case, but it does come with the problem of having to teach users how to find and copy the access cookie. It would be nice to find a more user-friendly way of getting the access cookie (or something similar).
We want to code a web-application (with ASP.NET Core) that starts a legacy Windows desktop application via a custom URL protocol. The web-application must use an authorization server for obtaining an access (bearer) token via OAuth 2 with which it has access to the user's resources via an ASP.NET Core Web API. The desktop application must be able to access the user's resources via the Web API too. How can the desktop application obtain an access token?
I can think of the following options:
The desktop application shows a login screen, sends the entered username and password to the authorization server (using the “Resource Owner Password Credentials” grant type of OAuth 2) and gets an access token back.
The desktop application shows an embedded browser window. The embedded browser requests the OAuth Authorize endpoint of the authorization server (using the “Authorization Code” grant type of OAuth 2) and the user must log-in to authorize. The authorization server redirects back to the redirect URL. The desktop application intercepts this redirect, extracts the authorization token and uses it to get an access token.
The web-application starts the desktop application and passes its access (bearer) token as an argument to the desktop application.
Before starting the desktop application, the web-application requests a new authorization code from the authorization server. The web-application starts the desktop application and passes the authorization code as an argument to the desktop application. The desktop application exchanges the authorization code for an access token by sending the authorization code to the OAuth Token endpoint of the authorization server.
We do not wish to use the first and second option, because we want single sign on.
The third option does not seem to be a good idea, because malicious software on the user’s desktop PC can obtain and use the access token too.
The fourth option seems to be the only option left. As far as I know an authorization code is a temporary (short-lived) one-time token. Besides that, you need to know the client secret for obtaining an access token.
Can anyone confirm that option four is the way to go? Or did I overlook something?
Are there any examples with IdentityServer for this scenario?
Both application should share a logon session using the system browser. This way the user gets SSO in the native app (and even vice versa).
The spec describes the best practices for native apps:
https://datatracker.ietf.org/doc/html/draft-ietf-oauth-native-apps-12
In your case there is a flow that is made specially for desktop application:
Client Device Flow for OpenID connect allows Application that do not have any "browser capability",this Flow will typically suit well Desktop applications.
I'm working on an command line utility that requires access to a backend server over a REST API.
I'm trying to avoid implementing my own authentication mechanism and use one (or more) of the public auth services (like google, Facebook, amazon).
I am trying to make the client accept credentials and authenticate against the authentication provider and do that without asking the user go open a web browser and provide back a token. The client will be open sourced in order to avoid trust issues (i.e. the user credentials are not sent to my backend server).
I am not interested in authorization, I only care of authenticating against my backend server without having the user keep yet another set of credentials (and without sending the user credentials to my backend server).
How can I have my client authenticate with the auth provider and get a token to communicate back with my server without having the user use a web browser?
I realize you said "not open a web browser", but what about if that browser is on another device (e.g. their mobile?).
If that is acceptable, you can use the OAuth 2.0 for Devices approach, whereby you present the user a short alphanumeric code, which they enter on http://google.com/device to authenticate the request from another device. This OAuth flow is designed to work in environments which don't have browsers (like a command line).
To see a demo of this authentication flow in action, visit the YouTube TV site, press the ← key on your keyboard, and select Sign In.
It's also easy to try out yourself – create a OAuth client in the developers console (of type "installed application" -> "other"), and follow the curl examples in the docs (be sure to replace the demo code in the token request with the device_code received from the initial request to the code endpoint). Decode the resulting id_token using any of the example JWT decoders, like this one.
In your case, you should request the profile scope, which will return an id_token in the response to your token endpoint call, from which you can extract the user's Google profile id (the id token's sub field).
i wonder how do desktop apps without any domain names use oauth? or is it not supposed to be used this way? if so what do i use? say for tumblr they have an authentication api so i will have to put the username and password in the url/query string?
i am thinking of using WPF/Adobe AIR. how does something like tweetdeck work?
I've been puzzled by the same question about lack of domain or app url, but it turns out redirection is not the only possible way to complete OAuth authentication process.
I.e., when webapp requests access it provides callback url: the one user will be redirected to when process is completed. That's how webapp know that everything's done.
But you can't redirect to application on user's machine. Thus, there's another way: upon successful authentication server presents special code to the user. Then user copies this code and provides it to application.
You can see both ways described in specification draft.
Also, here's an example of this authentication flow with twitter.
It looks like it may be possible, see googles docs on the subject:
https://developers.google.com/identity/protocols/oauth2/native-app
For a desktop app where a user needs to authenticate himself, you will usually want to use the Authorization code flow.
The approach goes roughly like this:
setup a temporary webserver that listens on the loopback interface
present the login page to the user (either in an embedded browser control or an external browser), with the URL of your temporary webserver as redirect_url
upon successful login, the user will be redirected to your temporary webserver and you can obtain the access code from the code query parameter
Using the access code, you can obtain a token and start making requests using it
Shutdown the temporary webserver
Please note that you will have to allow localhost as redirect URL in your identity provider, in ordrer for this approach to work.
For further details, please take a look at these sample apps from Google.
You should start by reading about getting started with OAuth. Eventually, even a desktop application will open a browser window to authenticate the user - TweetDeck and other Twitter clients do this, as you've probably noticed.
Tumblr, in your example, doesn't use OAuth but rather basic authentication that is being performed via simple HTTP web requests.
Twitter doesn't want users entering their credentials into your application. So at some point the desktop app will need to open a browser window through which Twitter can authenticate their users and return an access token representing the user. From that point the desktop app can use the access token to represent the user in all subsequent API calls to Twitter.
In a desktop environment you have another way to get the token, the browser open url itself.
the OAuth2 server will redirect the users browser to the Redirect URL with the token as a query parameter, so if you control the browser used, you can read the the token directly from the url that the user was redirected to.
Graphical libraries like GKT+ have integrated options to create mini browsers that the user can use to authenticate, and it automatically return the token to the app, but other options are possible, like reading Firefox url for example.