For Web Server applications, Google says to use the application type 'Web Application' - see:
https://developers.google.com/identity/protocols/OAuth2WebServer
But from testing, this appears to allow the end user to change the response_type in the url the user is sent to from 'code' to 'token' which then allows them to get an access token directly back at the end of the authentication flow.
Some other API providers provide a mechanism in the setup screen for the OAuth application to disable this auth flow completely which seems sensible.
Am I missing something here?
Related
According to the OAuth2.0 spec and the way it is implemented in OpenIddict 3.1.1, an authorization code should be retrieved by performing a GET request to the authorization endpoint. This will then redirect the user to a login page (if needed) and ask for explicit authorization from the user.
It is, however, also possible to configure a client application to use an implicit consent type, where the user does not need to explicitly give permission to the application.
My question builds on this: If I know that the user is already signed in (I have a valid access token), would it be possible to request an authorization code for a different application through a backchannel POST request (using the authorization header to specify that I have access to do this) instead of having to go through the browser for this flow?
As far as I can see in OpenIddct 3.1.1, the authorization code is generated in some middleware that handles signin results. This seems to make it difficult for me to generate such an authorization code in a custom endpoint designed for my desired scenario mentioned above.
The reason I'm wondering about this at all is because I'm building a desktop application for which I'll open a browser for the initial login, but after that I need to request an authorization code for a custom server back-end and I'd prefer not having to open the browser once more just for this purpose, since I know the user is authenticated (and authorized) to request this authorization code anyway. I would of course send the all the required information in this backchannel POST request (client_id, code_challenge, challenge_method, scopes...)
EDIT:
The reason I need a second access token is because:
I have 4 systems:
Desktop application
Custom Server
Resource Server
Identity Provider
The desktop application is the one that is directly used by the user, and it will request an access token through the regular auth_code flow from the Identity Provider. This desktop application will then request resources in the resource API, for which it needs an access token. This process is working as standard.
Now I also want the Custom Server application to request resources from the resource server. Normally you would use client credentials for this, because it is server to server, but the resources are owned by the user, so I'd want an access token specifically for these resources.
For this I now start a second auth_code flow on the desktop application to request an authorization code for the Custom Server. I then send this auth_code back to the Custom Server, which exchanges it for an access token. This works, but I would prefer if I didn't have to start a full on auth_code flow on the desktop application for this second process, as I know that the user is authorized to request this auth_code, and the consent type for the Custom Server is implicit in this case.
I'm immensly confused as to which OAUTH/OIDC flow to use when...
I've put together the following list to work through the options, and would appreciate someone correcting me if I'm getting it wrong. Thank you.
What I think I've understood so far is the following use cases:
A server-generated views web app (eg: ASP.NET or ASP.MVC based) that is refreshing on every request, and does not use AJAX to access authenticated APIs: use authorization code grant type flow.
A server-generated views web app (eg: ASP.MVC based) that is refreshing often, but does use AJAX to access authenticated APIs, and the server does not access 3rd parties APIs either as itself (the app) or on behalf of the user: use authorisation code grant type flow
server set session cookie to access APIs.
A server-generated views web app (eg: ASP.MVC based) that is refreshing often, but does use AJAX to access authenticated APIs, and the server does access 3rd parties APIs as itself (the app): use authorisation code grant type flow
server set session cookie to access APIs + use client credential grant type flow.
A client-side generated views web app (SPA), where the client invokes authenticated API endpoints on its source server, and the server does not invoke 3rd parties services as either itself (the app) or as the user: use implicit grant type flow, caching the authentication token in the user agent's sessionstorage, and passing the authentication_token* back on every request as a Bearer Token.
A client-side web app (SPA), where the client invokes authenticated API endpoints on its source server, and the server does invoke 3rd parties services as itself (the app): use implicit grant type flow, caching the authentication token in the user agent's sessionstorage, and passing the authentication_token back on every request as a Bearer Token, and use the client credential grant type flow*.
This probably is the most uncertain one: A client-side web app (SPA), where the client invokes authenticated API endpoints on its source server, and the server does invoke 3rd parties services as the the user: use implicit grant type flow, caching the authentication token in the user agent's sessionstorage, and passing the authentication_token back on every request as a Bearer Token, which the server can pass on to the 3rd party services (CHECK) to authenticate the user with. As the token is only encoded and signed, not encrypted, the token's claims can be read. Note: that may contain claims not intended for the 3rd party service.
Alternatively the flow might be:
The UI could precheck that the User is allowed to access the 3rd party service (eg: Order Flowers) and gray out the functionality to use the server api that will invoke the 3rd party service till the user has collected and stored a second authorisation token (but then how would the user agent pass that token back, if the call to the API was already using the authorisation header for its own bearer token?)
The OAuth2 spec defines a Client Credential grant for machine-to-machine authorization, where a user isn't involved. Identity is confirmed via a client secret. This isn't appropriate for a native client, such as a mobile application, because stored client secrets can't be guaranteed.
Mobile apps can make use of the OAuth Code Authorization grant plus Proof Key for Code Exchange (PKCE), which allows a dynamically generated secret. This is great if you need user authorization/authentication.
However, what if you just need to protect your API's resources so that only your mobile app can use it, but you don't track users? That is, I'd like to get an access token for my application, instead of for a user.
It seems like Code Authorization + PKCE would work great, if only both the login and consent screens could be disabled. Just return the auth code. I was hoping to find a way to do this in IdentityServer3, but haven't.
Is there a configuration or flow that allows this? Or am I making a security mistake?
EDIT
It further seems to me that using PKCE should allow for a flow with two backchannel calls, one to the authorize endpoint, the other to the token endpoint. Essentially, Code Authorization without the browser redirection. I know such a flow isn't in the spec, but am I right? Regardless, the question remains, how to authorize a mobile app using its own account, not a user's?
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 am working on a AngularJS web app and I am trying to implement single sign on. I had a nice implementation using Identity server and authorization server with implicit flow and oAuth tokens, however I need a mechanism to sign the user out of all apps they are signed into.
I am currently redirecting the user to authorization server, this then redirects the user to identity server. The user logs on and it shown a consent screen, a Json web token is then sent to the app via the query string and is put into local storage. This token is attached to the Authorization header which the web api (that is on a different domain) receives and either allows or denies the request.
The problem is oAuth has no way of singing a user out of all apps. I have now looked at WS-Federation using Json web tokens but this approach still appears to use cookies which I would like to avoid as the api and client app are on different domains.
Does Thinktecture Identity Server have any way to do this and if so are there any examples I could take a look at.
Thanks
As you already said - OAuth2 is not an authentication protocol and hence does not have the concept of (single) signout.