-
Notifications
You must be signed in to change notification settings - Fork 92
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Question: OAuth Client Type for native apps #24
Comments
Jose, you are interpreting the documentation correctly. OAuth requires that authentication providers distinguish between public and confidential clients and configuration time. However, Bungie.net has no mechanism to determine that the client really is confidential at run time. |
It's too bad that there isn't some refresh token setup for public clients because it drives folks who should be using a public client type to configure a confidential client type and putting their credentials at risk. |
Refresh tokens are literally equivalent to a credential until used, so to
some extent they aren't any safer in a public client than the actual
credential.
…On Mon, Aug 28, 2017 at 2:24 PM, vpzed ***@***.***> wrote:
It's too bad that there isn't some refresh token setup for public clients
because it drives folks who should be using a public client type to
configure a confidential client type and putting their credentials at risk.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#24 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAFqDD1WQfIR9Q6TJio7BZiIDXYE9hugks5sczATgaJpZM4PFBjw>
.
|
What actions will be taken if a mobile application registers as confidential and transmits their client_secret through the user's device? To force a user to open a new browser tab every 60 minutes is a bit strange. |
So, yeah, any native application could be subject to decompiling, or some inspection of app resources, so it's assumed that anything included in the application binary could be extracted. For public clients, that would be your API Key. On the other hand, the OAuth spec believes that native apps can provide adequate security for tokens.
Of course, anything that goes over the wire could be intercepted using a proxy. The same is true for the official Destiny app, which seems to use a cookie based authentication mechanism. From a user experience perspective, forcing a user to sign in every hour is awful. iOS or Android users might sign in twice, but by the third time you pop a web browser they'll give you a one star review and uninstall your app. It would be difficult to develop anything useful with such a restriction in place. Could you consider providing refresh tokens to public clients? |
I assume the Bungie iOS app uses the "confidential" client method, and I
know that every other mobile app does as well, as the usability impact of
"login every hour" is absolutely 100% unacceptable. So no matter what the
docs say, your iOS app should use "confidential". If that's unacceptable to
the docs, the docs need to be updated.
…On Wed, Aug 30, 2017 at 7:16 AM, Jose Ibanez ***@***.***> wrote:
So, yeah, any native application could be subject to decompiling, or some
inspection of app resources, so it's assumed that anything included in the
application binary could be extracted. For public clients, that would be
your API Key.
On the other hand, the OAuth spec believes that native apps can provide
adequate security for tokens.
...dynamically issued credentials such as access tokens or refresh tokens
can receive an acceptable level of protection. At a minimum, these
credentials are protected from hostile servers with which the application
may interact. On some platforms, these credentials might be protected from
other applications residing on the same device.
Of course, anything that goes over the wire could be intercepted using a
proxy. The same is true for the official Destiny app, which seems to use a
cookie based authentication mechanism.
From a user experience perspective, forcing a user to sign in every hour
is awful. iOS or Android users might sign in twice, but by the third time
you pop a web browser they'll give you a one star review and uninstall your
app. It would be difficult to develop anything useful with such a
restriction in place.
Could you consider providing refresh tokens to public clients?
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#24 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAFqDECIIQrkOO5_18PqfhIKU5CwYycXks5sdW6zgaJpZM4PFBjw>
.
|
@floatingatoll Their iOS application still uses a web-view, as @jose-ibanez pointed out. |
Yeah, it sure does. I hadn't filed a bug about that yet because Apple will
eventually reject their app for guidelines as a result, so I can safely
assume they'll fix it =)
…On Wed, Aug 30, 2017 at 2:15 PM, thisbarker ***@***.***> wrote:
@floatingatoll <https://github.com/floatingatoll> Their iOS application
still uses a web-view, as @jose-ibanez <https://github.com/jose-ibanez>
pointed out.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#24 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAFqDLLzU_I-FMLbaXN57r9tyFxVHGkPks5sddD7gaJpZM4PFBjw>
.
|
Good conversation, thank you all for the input! When we get time, I'll loop back around and investigate further, and discuss options and opinions mentioned here with the rest of the team. We're pressed for time at the moment, but I just want to make sure you guys know that we're not dropping the issue and will loop back. |
Agreed. Any observations from the industry in general. How do other apps/oauth servers deal with this problem? |
Those are just profiles to help base a decision on what OAuth flows to use I think. They define a confidential client as one that can maintain a secret regardless of how it is implemented. So if you're able accomplish that then you should safely be able to run as a confidential client. If you cannot accomplish that then you should not be issued a refresh token. As mentioned refresh tokens are equivalent to credentials. The supplemental info on the security considerations of the OAuth spec mention in section 4.1.1 different threat models - including accessing secrets.
In section 3.7 it mentions:
Now for section 5.2.3.4:
Basically if Bungie came up with a way to automate issuing of client ids and secrets we could "turn otherwise 'public' clients back into 'confidential' clients." ~~~Unfortunately such a thing isn't defined in the spec. I have no idea how feasible it would be for them to implement if it's even a good idea to do so.~~~ I haven't read all of this damned thing so there are probably other solutions for what we have currently. In my case I'm trying to build a web app so the web crypto api seemed like something that could help. Possibly the user-agent would retrieving the id and secret from a server at runtime and store them encrypting/decrypting on use. You would of course have to ensure only the proper clients can get the id and secret. If secure storage is possible then it seems the only problem is handling the id and secret. As mentioned you can't hardcode them as they would basically be public. Some sort of secure delivery mechanism would need to be put in place. ~~~But I'm still not sure how necessary it is to protect those two elements... It could be possible that exposing them would not be a big problem. In which case running as confidential would only require having some place to secure the tokens.~~~ |
Turns out there is a spec for dynamic registration: RFC7591. Something else that seemed interesting was the Assertion Framework (An abstract framework for OAuth client credentials/grants) And again concerning the question about native app there is this spec draft that mentions in section 8.4:
|
Wanted to implement a litte app and i can't realy decide which client model i should use. I still can't quite understand the difference between public and confidential Clients. (is it only the 3600s lifetime of the access token vs the 90days refresh token?) To my understanding there is not such a think like a confidential client (every client could expose there secrect keys though debbuging), like DIM exposes there client_id and client_secret upon every token refresh in there http request. Likewise Braytech for example exposes it via the Authorization header as there client_sec and client_id in a base64 encoded string. Why? Should'nt they use some kind of proxy, where the proxy only knows the secrets api keys and only pass the access or refresh token back to the client? What should i choose? The burden of relogging every hour in my app is kind of cumbersome and proxying could drastically increase traffic on my side? (If and only when the app find its users...) |
It's an age old question. The confidential client gets a refresh token which means the user won't need to sign in again for a year as long as they use your app every 90 days. The public client requires the user sign in once an hour. It is the most secure option for your scenario and really the only option if you are following the rules carefully (not everyone does). The user experience may not be as bad as you are imagining. Most of the time, the re-signin will happen without the user having to enter a user ID or password. I advise against creating a proxy; it becomes a point on the open internet someone can attack and leverage to attack Bungie.net. You would also need to have it authenticate each of your users which is a complex task and hard to get right. You may be tempted to have a secret your proxy can verify that only your app knows, but that is the same as keeping the client secret in your app. You may as well just put the client secret in that app and not have the headache of a proxy. My advice, try it as a public client first. It is easy to upgrade to a confidential client later if you must. You may find your scenario works well as a public client. |
thank you for quick answer. I will try as you say and go with the public client settings. Will see what the login, (which is maybe somehow cookied by the browser?) looks like. |
The access token, which you need to add to each request header per the OAuth spec, will not be cookied by the browser. Depending on your platform, you can probably find a pre-rolled OAuth client. For example, I think npm has a few to choose from. |
A potential solution to this would be to implement PKCE on the server side. This adds a significant layer of security for the code exchange process and is already baked into some OAuth client libraries. I was just running into the missing |
PKCE is not a replacement for refresh tokens. The OAuth.net featured post for implementing PKCE indicates that PKCE is a safer way to retrieve an access token — but also shows that it's still retrieving a one-hour access token:
Auth0 also reversed their prior recommendation of PKCE alone and now indicates refresh token rotation alongside PKCE as their current guidance:
If you expect users of your app to use your app for longer than 1 hour, or more than 1 time per 7 days, then the 'public' scope is inappropriate for your app; you'll need 'confidential' scope, and you'll need to handle refresh tokens. |
Sorry I didn't mean to imply that PKCE flow was a alternative to using refresh tokens. I was suggesting that Bungie look into adding a PKCE enabled OAuth flow so we can avoid embedding the Client Secret in our native apps (aka SPA). I haven't yet come across any OAuth flows that use such an aggressive refresh token rotation strategy as listed in that documentation. Thanks for that info. |
I'm developing an iOS app that uses the Bungie API, and it seems that any native application developed using the Bungie.Net API that requires user authentication would be forced to re-authenticate users every hour.
Reading Bungie.Net API's OAuth Documentation, I am supposed to select an OAuth Client Type for my application "as described in section 2.1 of the OAuth 2.0 specification." RFC 6749 clearly states that "A native application is a public client installed and executed on the device used by the resource owner." Then, I also see back in your OAuth documentation that "A public client differs from a confidential client in that... it will not receive a refresh token in response to a token request." So, if I'm reading this correctly, any native app will have to re-authenticate the user every hour, which is obviously not ideal.
Am I misinterpreting the documentation? Could a native app be considered a confidential client if the API Key is stored in the application binary in an encrypted format and any transient tokens are stored in the OS's secure storage, such as iOS's Keychain? If not, would you consider providing public clients refresh tokens?
The text was updated successfully, but these errors were encountered: