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?)
Related
I`m new to OAuth 2.0 and am trying to develop a application using a third party OAuth provider with Authorization Code grant flow as ny Authorization Server and Spring Security.
This provider gives me two endpoints /authorize and /token and those two, after the user authorizes its access, will return a access token.
So far, I have secured the "/" endpoint, so the application redirect the user to the authorization page and then, in the callback endpoint, store the token so it can be validated by a filter in each request.
But, as the application is mainly a set of REST API's, we want to be able to test it using Postman, with that said, on Postman, I am getting the token by setting the Authorization as OAuth 2.0 and requesting the token directly from the third party endpoints but, as Postman have its own callback URI, my application doesn`t store the token generated.
So, my two questions on this are:
Using /callback endpoint to store the token and validating it before each request by a filter is the common way of doing it?
To use Postman, should I create an endpoint for storing the token generated outside the application context or should I create an Authorization Server of my own as an additional layer on top of this third party AS?
Since your application is a set of REST API's, you need to make it as a Resource Server (in terms of OAuth2).
Resource Server doesn't perform authentication itself, it only validates a token from Authorization header (Resource Server in a nutshell).
You can find an example in Spring Security samples: oauth2resourceserver
I eventually come to the conclusion that I was using Postman wrong the whole time.
So, by the end, we got the Token saved on the database when the user logs in and, then, return it to the caller, whether it is the Front-end application, or Postman itself.
Then, in every call to the API's, the caller should include the token as Authorization on the header and a Filter on Spring will check the token against the Database.
I am building an Angular SPA app and using Okta as an Idp. since its an SPA so I think I need to use Implicit flow. I have two queries here-
Since in Implicit flow a refresh token is not issued, does it means that th user will be logged out of the app after the token expires and he has to log in again?
Why do I need to use Implicit flow in case of SPA? why not Authorization code flow? since I have control over both the front end (SPA) and back end (REST API) . for example in case of Spring MVC architecture for the web app Authorization code flow is possible.
Thanks,
pchh
Yes, if the token expired, you have to re-autenticate. Normally you still have a valid session on the identity providers site, so you can do a "silent" login using an iframe. Libraries like oidc-client support a silent login, which can do this for you.
You need to use implicit (or hybrid) flow, when you need to access to the access token from your javascript app. With authorization code flow your javascript app doesn't get the access token, so if your API needs an access token for authorization, what are you going to send?
If your auth server supports OpenID Connect (OAuth2 extension) and single sign-on (SSO) feature, to get a new token before the old gets expired, use an iframe with a URL you used for authentication, but add prompt=none parameter (and possibly id_token_hint parameter). See OpenId Connect RFC. The prompt=none parameter tells the /auth endpoint to issue a new token(s) if the user has an open SSO session at your OAuth2 server. If not, the request will fail. There is a separate RFC for session management.
The Authorization code flow requires you to access the /token endpoint, which usually requires authentication (client ID + client secret) and you cannot keep the secret safe in a browser. For this reason, the token endpoint doesn't use to support CORS headers, so you cannot access it using XHR. Using the Auth code flow, you get a code as a redirect URL param (?code=), which gets to the server hosting your SPA (browser sends it there after redirect). The implicit flow returns tokens in hash part of the redirect URL (#access_token=), which stays in a browser (it's not sent to the server), so it's safer.
I'm learning about O Auth 2 from here
I was wondering in the step of "Authorization server redirects user agent to client with authorization code", why doesn't the server just give the access token instead? Why give an authorization code that then is used to get the access token? Why not just give the access token directly? Is it because there there is a different access token for each resource so that you need to go through O Auth again to access a different resource?
The authorization grant code can pass through unsecured or potentially risky environments such as basic HTTP connection (not HTTPS) or a browser. But it's worthless without a client secret. The client can be a backend application. If the OAuth2 server returned a token, it could get compromised.
There is another OAuth2 flow - the Implicit flow, which returns an access token right after the authentication, but it's designed mainly for JavaScript applications or other deployments where it's safe to use it.
If a malicious app gets hold of the client id of your app(which is easily available, for example one can inspect the source), then it can use that to retrieve the token without the use of the client secret. All the malicious app needs to do is to somehow either specify the redirect URI to itself or to tap into the registered redirect URI.
That is the reason for breaking the flow as such. Note, when the client secret is not to be used as in SPA (Single Page Apps) or Mobile Apps, then PKCE comes to the rescue.
There is a reason for breaking up the authorization flow so as to keep the resource owner's interaction with the authorization server isolated from the client's interactions with the authorization server. Therefore we need to have two interactions with the authorization server. One in which the resource owner authenticates with it's credentials to the authorization server. And another where the client sends in it's client secret to the authorization server.
Please also see PKCE that deals with SPA (SinglePageApp)/Mobile apps.
I have an OIDC server setup for authentication and authorization. And I also have a desktop application which is essentially a browser with some extra functions.
The application makes calls to a API server directly and the embedded browser visits a web application that also makes requests to the same API server. Everytime the application is executed, user is required to login once.
Should I use hybrid flow? Can the tokens be shared between the app and web app?
I would also like to know how does the Facebook mobile app do authentication with its native part and web view part.
Edit: the web application is a server side MVC application
If the web application is an SPA, and thus a public client, then you can simply use the implicit grant type and pass the access and ID tokens from the embedded browser to the native application.
But assuming the web application is a server side application and thus a confidential client, then you would most likely want to use the authorization_code flow as the basis, since it will give you access to a refresh_token if needed on the server and you can rely on the Authorization Provider's TLS certificate for trust.
You can now choose whether to render back the access token from the server to the frontend, or to use a hybrid flow as you say. The latter would allow you to already pass the ID Token and access token to the native application without waiting for the backend call to the token endpoint and the page refresh to complete.
However, when processing tokens client side you must verify the ID Token signature and match the access token to it via at_hash since you can't rely on the TLS certificate of the token endpoint in that case.
OAuth 2.0 has multiple workflows. I have a few questions regarding the two.
Authorization code flow - User logs in from client app, authorization server returns an authorization code to the app. The app then exchanges the authorization code for access token.
Implicit grant flow - User logs in from client app, authorization server issues an access token to the client app directly.
What is the difference between the two approaches in terms of security? Which one is more secure and why?
I don't see a reason why an extra step (exchange authorization code for token) is added in one work flow when the server can directly issue an Access token.
Different websites say that Authorization code flow is used when client app can keep the credentials secure. Why?
The access_token is what you need to call a protected resource (an API). In the Authorization Code flow there are 2 steps to get it:
User must authenticate and returns a code to the API consumer (called the "Client").
The "client" of the API (usually your web server) exchanges the code obtained in #1 for an access_token, authenticating itself with a client_id and client_secret
It then can call the API with the access_token.
So, there's a double check: the user that owns the resources surfaced through an API and the client using the API (e.g. a web app). Both are validated for access to be granted. Notice the "authorization" nature of OAuth here: user grants access to his resource (through the code returned after authentication) to an app, the app get's an access_token, and calls on the user's behalf.
In the implicit flow, step 2 is omitted. So after user authentication, an access_token is returned directly, that you can use to access the resource. The API doesn't know who is calling that API. Anyone with the access_token can, whereas in the previous example only the web app would (it's internals not normally accessible to anyone).
The implicit flow is usually used in scenarios where storing client id and client secret is not recommended (a device for example, although many do it anyway). That's what the the disclaimer means. People have access to the client code and therefore could get the credentials and pretend to become resource clients. In the implicit flow all data is volatile and there's nothing stored in the app.
I'll add something here which I don't think is made clear in the above answers:
The Authorization-Code-Flow allows for the final access-token to never reach and never be stored on the machine with the browser/app. The temporary authorization-code is given to the machine with the browser/app, which is then sent to a server. The server can then exchange it with a full access token and have access to APIs etc. The user with the browser gets access to the API only through the server with the token.
Implicit flow can only involve two parties, and the final access token is stored on the client with the browser/app. If this browser/app is compromised so is their auth-token which could be dangerous.
tl;dr don't use implicit flow if you don't trust the users machine to hold tokens but you do trust your own servers.
The difference between both is that:
In Implicit flow,the token is returned directly via redirect URL with "#" sign and this used mostly in javascript clients or mobile applications that do not have server side at its own, and the client does not need to provide its secret in some implementations.
In Authorization code flow, code is returned with "?" to be readable by server side then server side is have to provide client secret this time to token url to get token as json object from authorization server. It is used in case you have application server that can handle this and store user token with his/her profile on his own system, and mostly used for common mobile applications.
so it is depends on the nature of your client application, which one more secure "Authorization code" as it is request the secret on client and the token can be sent between authorization server and client application on very secured connection, and the authorization provider can restrict some clients to use only "Authorization code" and disallow Implicit
Which one is more secure and why?
Both of them are secure, it depends in the environment you are using it.
I don't see a reason why an extra step (exchange authorization code
for token) is added in one work flow when the server can directly
issue an Access token.
It is simple. Your client is not secure. Let's see it in details.
Consider you are developing an application against Instagram API, so you register your APP with Instagram and define which API's you need. Instagram will provide you with client_id and client_secrect
On you web site you set up a link which says. "Come and Use My Application". Clicking on this your web application should make two calls to Instagram API.
First send a request to Instagram Authentication Server with below parameters.
1. `response_type` with the value `code`
2. `client_id` you have get from `Instagram`
3. `redirect_uri` this is a url on your server which do the second call
4. `scope` a space delimited list of scopes
5. `state` with a CSRF token.
You don't send client_secret, You could not trust the client (The user and or his browser which try to use you application). The client can see the url or java script and find your client_secrect easily. This is why you need another step.
You receive a code and state. The code here is temporary and is not saved any where.
Then you make a second call to Instagram API (from your server)
1. `grant_type` with the value of `authorization_code`
2. `client_id` with the client identifier
3. `client_secret` with the client secret
4. `redirect_uri` with the same redirect URI the user was redirect back to
5. `code` which we have already received.
As the call is made from our server we can safely use client_secret ( which shows who we are), with code which shows the user have granted out client_id to use the resource.
In response we will have access_token
The implicit grant is similar to the authorization code grant with two distinct differences.
It is intended to be used for user-agent-based clients (e.g. single page web apps) that can’t keep a client secret because all of the application code and storage is easily accessible.
Secondly instead of the authorization server returning an authorization code which is exchanged for an access token, the authorization server returns an access token.
Please find details here
http://oauth2.thephpleague.com/authorization-server/which-grant/
Let me summarize the points that I learned from above answers and add some of my own understandings.
Authorization Code Flow!!!
If you have a web application server that act as OAuth client
If you want to have long lived access
If you want to have offline access to data
when you are accountable for api calls that your app makes
If you do not want to leak your OAuth token
If you don't want you application to run through authorization flow every time it needs access to data. NOTE: The Implicit Grant flow does not entertain refresh token so if authorization server expires access tokens regularly, your application will need to run through the authorization flow whenever it needs access.
Implicit Grant Flow!!!
When you don't have Web Application Server to act as OAuth Client
If you don't need long lived access i.e only temporary access to data is required.
If you trust the browser where your app runs and there is limited concern that the access token will leak to untrusted users.
Implicit grant should not be used anymore, see the IETF current best practices for details. https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics-18#section-2.1.2
As an alternative use a flow with response type code; for clients without possibility to securely store client credentials the authorization code with PKCE flow should be your choice.
From practical perspective (What I understood), The main reason for having Authz code flow is :
Support for refresh tokens (long term access by apps on behalf of User), not supported in implicit: refer:https://www.rfc-editor.org/rfc/rfc6749#section-4.2
Support for consent page which is a place where Resource Owner can control what access to provide (Kind of permissions/authorization page that you see in google). Same is not there in implicit . See section : https://www.rfc-editor.org/rfc/rfc6749#section-4.1 , point (B)
"The authorization server authenticates the resource owner (via the user-agent) and establishes whether the resource owner grants or denies the client's access request"
Apart from that, Using refresh tokens, Apps can get long term access to user data.
There seem to be two key points, not discussed so far, which explain why the detour in the Authorization Code Grant Type adds security.
Short story: The Authorization Code Grant Type keeps sensitive information from the browser history, and the transmission of the token depends only on the HTTPS protection of the authorization server.
Longer version:
In the following, I'll stick with the OAuth 2 terminology defined in the RFC (it's a quick read): resource server, client, authorization server, resource owner.
Imagine you want some third-party app (= client) to access certain data of your Google account (= resource server). Let's just assume Google uses OAuth 2. You are the resource owner for the Google account, but right now you operate the third-party app.
First, the client opens a browser to send you to the secure URL of the Google authorization server. Then you approve the request for access, and the authorization server sends you back to the client's previously-given redirect URL, with the authorization code in the query string. Now for the two key points:
The URL of this redirect ends up in the browser history. So we don't want a long lived, directly usable access token here. The short lived authorization code is less dangerous in the history. Note that the Implicit Grant type does put the token in the history.
The security of this redirect depends on the HTTPS certificate of the client, not on Google's certificate. So we get the client's transmission security as an extra attack vector (For this to be unavoidable, the client needs to be non-JavaScript. Since otherwise we could transmit the authorization code via fragment URL, where the code would not go through the network. This may be the reason why Implicit Grant Type, which does use a fragment URL, used to be recommended for JavaScript clients, even though that's no longer so.)
With the Authorization Code Grant Type, the token is finally obtained by a call from the client to the authorization server, where transmission security only depends on the authorization server, not on the client.