We have an auth infrastructure based on OAuth2 that is integrated into a variety of web apps within our organization. We also have a pure native application with no middle-ware of its own, and we want to integrate authentication into this native application. This application already has its own internal login mechanism with a native login screen, and we don't want to have it start launching external components like web browsers in order to display login windows. We are both the app provider and the auth provider, so the concern of the app having visibility into the user's credentials is less of an issue -- we trust ourselves to not intentionally do anything untoward with the user's credentials, and it's the same people writing a login form in the app as writing it on a web site. :-)
We are trying to figure out how best to support having the application continue to collect credentials the way it does now, but use them to obtain an auth token within our auth framework. With the APIs in place right now, the only way I can see for it to be done is to bake a Client Secret into the native app so that it can use a Resource Owner Password Credentials Grant request, since the code that would normally be making this call doesn't have a server side to live in. This feels really wrong, somehow. :-P
As far as I can see it, many of the structures of OAuth don't really apply to this app because it's not living in the context of a web browser, it doesn't have any concept of a "domain" nor any sort of "cross-domain" restrictions. It has been suggested that perhaps we create middleware for this app just for the purpose of exchanging authentication codes for tokens, but the rationale for that seems to be that this middleware theoretically ought to be able to somehow vet requests to determine whether they are legitimately from the application, and I don't see any way to do that that couldn't be faked by anyone with access to the client application code. Basically, the only purpose such middleware would serve would be to make the Client Secret irrelevant with respect to getting auth codes for credentials.
One thought that came to us was, how does something like Windows do it? Windows very obviously uses a native login form, but then some flow exists whereby the credentials that are entered are used for authentication and presumably, deep in the internals of the OS, for obtaining an auth token. Does anybody know if this architecture is documented anywhere? Does Microsoft's architectural choices here have any relation to OAuth2? What is the "best practice" for an application if you take it as a given that it doesn't have middleware and has its own native login form?
FWIW you don't need a client secret to use ROPC Grant to obtain or refresh tokens if the client is configured as a public client, i.e. a client that isn't capable of storing a secret.
RFC8252 OAuth 2.0 for Native Apps encourages using a native user agent for your scenario, using authorization code flows with PKCE. Authorization services like Okta and Auth0 have jumped onboard too, although they still recommend ROPC if the client is "absolutely trusted".
RFC6819 OAuth 2.0 Security discourages ROPC, but also says "Limit use of resource owner password credential grants to scenarios where the client application and the authorizing service are from the same organization", which are first-party apps.
So while the security verdict seems to be that authorization code+PKCE is the best practice, the UX hurdle of showing a user a browser window to log into a native app seem to be keeping ROPC alive. It's difficult to tell if that UX is jarring because people aren't used to it or because people can't get used to it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With