OAuth2: Which flow to use? - oauth-2.0

There appears to be four distinct flows in OAuth2, i.e. (link),
Authorization Code Flow - used with server-side Applications
Implicit - used with Mobile Apps or Web Applications (applications
that run on the user's device)
Resource Owner Password Credentials - used with trusted applications
such as those owned by the service itself.
Client Credentials - used with Applications API access.
If I'm developing a mobile application that will consume resources from its own API, i.e., the mobile app is developed by the same team developing the API, which of the four OAuth flows should I use and how?
Given my scenario, it sounds to me like option 3 is the way to go. If this is the case, would you adopt the following process:
Release you mobile app with the ClientId and ClientSecret stored on
it (deemed okay as the application is trusted).
Ask the user to log into their account using cookie-based
authentication (immediately deleting their username and password).
Cache the hash of their username and password returned in the
response of the cookie-based authentication.
Use the cached username and password, along with the ClientId and
ClientSecret, to request access and refresh tokens from the token
endpoint of the OAuth server.
Doe this seem sensible? It would be good to know if I'm on the right track with the above thought process, or if I'm going something incredibly silly and ought to be doing this some other way.

Resource Owner Password Credentials flow would be okay for your case.
BTW, it is difficult for a mobile application to keep its client secret confidential (RFC 6749, 2.1. Client Types, RFC 6749, 9. Native Applications). Therefore, in normal cases, a client secret should not be embedded in a mobile application. In other words, embedding a client secret is almost meaningless in terms of security.

2- Implicit - used with Mobile Apps or Web Applications (applications
that run on the user's device)
If your application runs entirely on a mobile device then you are encouraged to use this flow as your mobile app can't be trusted to keep its client credentials secret.

Related

Oauth pkce flow impersonating someone else's client

For confidential clients, there are scopes assigned to clients and the logged in user has to consent to them. Since there is client secret involved in exchange of auth code for access token, no one can impersonate them and take advantage of their scopes.
But when it comes to pkce flow on a native app, if I had someone else's clientId (clientIds are not considered private information) which has a lot of scopes, I could just start the flow with with their clientId. What is stopping a hacker from using some reputed clientId in the PKCE flow and have access to all their scopes?
NATIVE CALLBACK METHODS
If you look at RFC8252, certain types of callback URL can be registered by more than one app, meaning only a client ID needs to be stolen in order to impersonate a real app, as you say.
This still requires a malicious app to trick the user to sign in before tokens can be retrieved. And of course each app should use only the scopes it needs, and prefer readonly ones. After that it depends on the type of native app.
MOBILE
A mobile app can use Claimed HTTPS Schemes via an https callback URL to overcome this. It is backed by App Links on Android or Universal Links on iOS. Even if a malicious app uses the client ID, it cannot receive the login response with the authorization code, because it will be received on a URL like this, and the mobile OS will only pass this to the app that has proved ownership of the domain via the deep linking rehistration process:
https://mobile.mycompany.com/callback?code=xxx
DESKTOP
For desktop apps there are gaps, since only Loopback and Private URI Scheme callback URLs can be used. It relies on users to avoid installing malicious apps. Eg only install apps from stores that require code signing, which also inform the user who the publisher is. If users install malicious apps then perhaps they have deeper problems.
ATTESTATION
A newer technique is to use a form of client authentication before authentication begins. For confidential clients, Pushed Authorization Requests are used, which uses the app's client credential, so this cannot be used by native clients by default.
Mobile apps could potentially provide proof of ownership of their Google / Apple signing keys during authentication, and there is a proposed standard around that.

Is it okay to use client credentials grant type for authentication of a WEB API going to be consumed by SailPoint(IAM)

I have an old windows application written in VB.NET with SQL server backend. Currently the new user additions, deletion, adding entitlements etc. are managed by an old approval workflow system. After getting approvals, the user details and entitlements are inserted in to the SQL server database table manually.
I am trying to integrate this application with the SailPoint's Identity and access management. So the new user addition, deletion update and adding entitlements etc will be done through Sailpoint. For this, I would require to create a WEB API which can be called by Sailpoint and expose the functionalities(add user/delete user/add entitlements). The only consumer to this API is SailPoint.
I am new to OAuth and below are the grant types that I came across. But not sure which one I should be using in this particular scenario.
1.Implicit Grant
2.Resource Owner Password Credentials Grant
3.Client Credentials Grant
4.Authorization Code Grant
I have done research on the different authentication methods that we can use to secure the web api. But still confused on which one to apply in this scenario as this new web api is going to be made available in internet.
I already tried developing a POC with the OAuth 2.0 with password grant type referring this article. But when I read articles in the internet I found that the password grant type is not that secure and is deprecated.
Could you please advise on which grant type(client credentials/authorization code/implicit) to use in this scenario. I believe authorization code is used when the user is directly trying to access the API. In this scenario, SailPoint will be calling the API in the backend programmatically when they insert a new user in their UI.
I think it's a good approach to use client credentials in this case because the communication between IIQ and your Web API can be considered an API-to-API communication, I mean, IIQ is acting on behalf of itself in this communication.
See this article for more details - https://dzone.com/articles/four-most-used-rest-api-authentication-methods (bold part by myself)
OAuth 2.0 provides several popular flows suitable for different types
of API clients:
Authorization code — The most common flow, it is mostly used for
server-side and mobile web applications. This flow is similar to how
users sign up into a web application using their Facebook or Google
account.
Implicit — This flow requires the client to retrieve an
access token directly. It is useful in cases when the user’s
credentials cannot be stored in the client code because they can be
easily accessed by the third party. It is suitable for web, desktop,
and mobile applications that do not include any server component.
Resource owner password — Requires logging in with a username and
password. In that case, the credentials will be a part of the request.
This flow is suitable only for trusted clients (for example, official
applications released by the API provider).
Client Credentials —
Intended for the server-to-server authentication, this flow describes
an approach when the client application acts on its own behalf rather
than on behalf of any individual user. In most scenarios, this flow
provides the means to allow users to specify their credentials in the
client application, so it can access the resources under the client’s
control.

Best practice for OAuth Tokens for a combination of native apps and backend processes

I have a scenario in which a mobile (native) app is requiring data from a long running task. The task is a continuesly running on the users behalf, and we have decided to move it to a backend service. To execute the task, the backend service must regularly fetch data from an API that is OAuth2 protected.
Our dilemma is that we are not sure how to provide the backend service with a set of access tokens to access the data API. Our mobile app uses the OAuth2 Authorization Grant flow with PKCS to get its own access token, refresh token and id-token (we use OpenID Connect). But how do we provide our backend service with a set of tokens? As the backend is continuesly running (also in absence of the mobile native app) we would like to provide it with its own set of access/refresh tokens.
There seem to be several solutions:
Proxy all mobile app communication to external APIs via the backend, make the client a private client, use the authorization code flow, and setup custom login sessions between the native app and our backend. To me this means more running backend infrastructure, and implementing session management including session refresh, etc. which is like re-implementing the OpenId flows on my own servers...
Using OpenID hybrid flow, providing both an access token as well as an authorization code to be shared with the backend. However, this seems to be directed at (in-browser) web-apps, not so much native mobile apps as it based on the implicit flow and as such less secure.
Doing the authorization code flow twice on the mobile app (optionally second time with prompt=none to suppress user interaction), keeping one code for the app, forwarding the second to the backend. Then both backend and app can exchange their own codes for access tokens. This feels a bit like a hack as the backend should be a private client, not a public client. It is the approach that Google seems to advertise though in CrossClientAuth
Performing impersonation by sending the id-token to the backend which then exchanges that id-token for its own set of access/refresh tokens. Microsoft does this through the jwt-bearer grant in its "on-behalf-of" scenarios. Moreover, the token-exchange RFC seems to cover the same use-case. However, in this scenario the id-token is indirectly used as access credential, not just as a bag of claims about the user identity, which is odd in my view as access should be controlled through access tokens, is it not? Moreover, not all services should be allowed to impersonate, so I suppose this comes with additional configuration complexity.
To me it feels that I'm overlooking something, this must be a problem others have too and must have been solved before... What would be best practice in my situation?

oauth2 openid connect javascript (electron) desktop application

What is the correct oauth2 flow for a desktop application? Besides a desktop application I have a SPA Web GUI which does use the Implicit flow. There it does not matters if the client Redirects after 3600s to the IdP to issue a new Access token.
But the desktop application needs to be running 24/7 or could be running 24/7. So it needs to automatically refresh the access token via a refresh_token. But since the implicit flow does not provide refresh tokens it is probably the wrong flow for a desktop app, isn't it?
I guess I need the auth code flow, which does provide a refresh_token. But authentication requests needs a redirect_uri. Let's say I want to use Google as my openid provider. With google it looks like I can't register client credentials with a custom URI scheme (https://developers.google.com/identity/protocols/OpenIDConnect). What does work is to register for example http://localhost:9300, which theoretically could be handled by the app.
A
Whats the correct oauth2 flow for a desktop app to receive a refresh_token?
B
Can I catch the redirect_uri via a custom URI scheme without using the implicit flow (Google IdP)? It is way easier to listen for a custom uri scheme than listening on a local tcp port.
C
This is more a general question. Usually desktop apps are public apps, so I should not include client_secret right? So the only flow which would be left is the implicit flow. But how can I renew access tokens according to specs without bother the desktop user every 3600s?
In my case I could publish the app locally so not public, but how is it for a public app?
A - Authorization Code Grant
B - Not sure here, You can register a Custom URI Scheme
C - Not enough information provided.
Are you using the AppAuth libraries? If so you SHOULD use PKCE and then additional security measures for the refresh token should not be necessary, on the assumption that the client never sends the refresh token with anyone other than the IDP over a secure connection.
Does this help?
A: Yes use the code grant
B: yes use a custom scheme. In your case you should use the reverse of your client ID. e.g. com.googleusercontent.apps.123 is the reverse DNS notation of the client ID. Register your client as "Other" in the Google developer console.
C: Yes, it should not include the client secret. That is why you don't need to send the secret for native clients ("Other") when exchanging the code for a refresh token. Just leave that field blank and it'll work.
As suggested by jwilleke, please use an AppAuth library if it is available for your use case as it'll also handle some of the security issues (PKCE).
For native apps (Desktop), you can follow OAuth 2.0 for Native Apps. But this is still under review and you can refer the latest draft from provided link.
With this flow, you can use authorisation code flow to obtain both access token and a refresh token. Refresh tokens should solve the UX related issue when it comes to extended app usage (24/7 and beyond).
According to this working document, there are strict guidelines on client authentication. Section 8.5 discuss about them. As it says client credentials are not recommended
For this
reason, and those stated in Section 5.3.1 of [RFC6819], it is NOT
RECOMMENDED for authorization servers to require client
authentication of public native apps clients using a shared secret
Also as nvnagr has mentioned in his answer, PKCE [RFC7636] is a must to have for native public clients.

OAuth 2 for native application - what is difference between public and confidential client types?

I trying to implement OAuth 2 provider for web service and then built native application on top of it. Also I want give access to API for third-party developers.
I read OAuth 2 specification already and can't choose right flow. I want authenticate both CLI and GUI apps as well.
First of all we have two client types - public and confidential. Of course both GUI and CLI apps will be public. But what is difference between this two types? In this case for what I need client_secret if I can get access token without it just by changing client type?
I tried to look at some API implementations of popular services like GitHub. But they use HTTP Basic Auth. Not sure it is a good idea.
Is there any particular difference? Does one improve security over the other?
As to the difference between public and confidential clients, see http://tutorials.jenkov.com/oauth2/client-types.html which says:
A confidential client is an application that is capable of keeping a
client password confidential to the world. This client password is
assigned to the client app by the authorization server. This password
is used to identify the client to the authorization server, to avoid
fraud. An example of a confidential client could be a web app, where
no one but the administrator can get access to the server, and see the
client password.
A public client is an application that is not capable of keeping a
client password confidential. For instance, a mobile phone application
or a desktop application that has the client password embedded inside
it. Such an application could get cracked, and this could reveal the
password. The same is true for a JavaScript application running in the
users browser. The user could use a JavaScript debugger to look into
the application, and see the client password.
Confidential clients are more secure than public clients, but you may not always be able to use confidential clients because of constraints on the environment that they run in (c.q. native apps, in-browser clients).
#HansZ 's answer is a good starting point in that it clarifies the difference between a public and private client application: the ability to keep the client secret a secret.
But it doesn't answer the question: what OAuth2 profile should I use for which use cases? To answer this critical question, we need to dig a bit deeper into the issue.
For confidential applications, the client secret is supplied out of band (OOB), typically by configuration (e.g. in a properties file). For browser based and mobile applications, there really isn't any opportunity to perform any configuration and, thus, these are considered public applications.
So far, so good. But I disagree that this makes such apps unable accept or store refresh tokens. In fact, the redirect URI used by SPAs and mobile apps is typically localhost and, thus, 100% equivalent to receiving the tokens directly from the token server in response to a Resource Owner Password Credentials Grant (ROPC) .
Many writers point out, sometimes correctly, that OAuth2 doesn't actually do Authentication. In fact, as stated by the OAuth2 RFC 6749, both the ROPC and Client Credentias (CC) grants are required to perform authentication. See Section 4.3 and Section 4.4.
However, the statement is true for Authorization Code and Implicit grants. But how does authentication actually work for these domains?
Typically, the user enters her username and password into a browser form, which is posted to the authentication server, which sets a cookie for its domain. Sorry, but even in 2019, cookies are the state of the authentication art. Why? Because cookies are how browser applications maintain state. There's nothing wrong with them and browser cookie storage is reasonably secure (domain protected, JS apps can't get at "http only" cookies, secure requires TLS/SSL). Cookies allow login forms to be presented only on the 1st authorization request. After that, the current identity is re-used (until the session has expired).
Ok, then what is different between the above and ROPC? Not much. The difference is where the login form comes from. In an SPA, the app is known to be from the TLS/SSL authenticated server. So this is all-but identical to having the form rendered directly by the server. Either way, you trust the site via TLS/SSL. For a mobile app, the form is known to be from the app developer via the app signature (apps from Google Play, Apple Store, etc. are signed). So, again, there is a trust mechanism similar to TLS/SSL (no better, no worse, depends on the store, CA, trusted root distributions, etc.).
In both scenarios, a token is returned to prevent the application from having to resend the password with every request (which is why HTTP Basic authentication is bad).
In both scenarios, the authentication server MUST be hardened to the onslaught of attacks that any Internet facing login server is subjected. Authorization servers don't have this problem as much, because they delegate authentication. However, OAuth2 password and client_credentials profiles both serve as de facto authentication servers and, thus, really need to be tough.
Why would you prefer ROPC over an HTML form? Non-interactive cases, such as a CLI, are a common use case. Most CLIs can be considered confidential and, thus, should have both a client_id and client_secret. Note, if running on a shared OS instance, you should write your CLI to pull the client secret and password from a file or, at least, the standard input to avoid secrets and passwords from showing up in process listings!
Native apps and SPAs are another good use, imo, because these apps require tokens to pass to REST services. However, if these apps require cookies for authentication as well, then you probably want to use the Authorization Code or Implicit flows and delegate authentication to a regular web login server.
Likewise, if users are not authenticated in the same domain as the resource server, you really need to use Authorization Code or Implicit grant types. It is up to the authorization server how the user must authenticate.
If 2-factor authentication is in use, things get tricky. I haven't crossed this particular bridge yet myself. But I have seen cases, like Attlassian, that can use an API key to allow access to accounts that normally require a 2nd factor beyond the password.
Note, even when you host an HTML login page on the server, you need to take care that it is not wrapped either by an IFRAME in the browser or some Webview component in a native application (which may be able to set hooks to see the username and password you type in, which is how password managers work, btw). But that is another topic falling under "login server hardening", but the answers all involve clients respecting web security conventions and, thus, a certain level of trust in applications.
A couple final thoughts:
If a refresh token is securely delivered to the application, via any flow type, it can be safely stored in the browser/native local storage. Browsers and mobile devices protect this storage reasonably well. It is, of course, less secure than storing refresh tokens only in memory. So maybe not for banking applications ... But a great many apps have very long lived sessions (weeks) and this is how it's done.
Do not use client secrets for public apps. It will only give you a false sense of security. Client secrets are appropriate only when a secure OOB mechanism exists to deliver the secret and it is stored securely (e.g. locked down OS permissions).

Resources