According to RFC-6750 A security token with the property that any party in possession of the token (a "bearer") can use the token in any way that any other party in possession of it can (without demonstrating possession of a cryptographic key).
Q1) Isn't this definition applies to username and password also because anyone in possession of a username and password can use it in the same way as any other party (maybe stolen the username & password) in possession of it can? In both cases (without demonstrating possession of a
cryptographic key). Is it because a token already contains permissions?
Thanks a lot
Both can be used by someone who steals them, as you say, but the key points about access tokens are that:
They are short lived (~60 minutes), unlike passwords
They represent only a subset of the user's permissions that a particular app needs
STEALING ACCESS TOKENS
Access tokens are also not easily stolen. An attacker may be able to get an access token for their own login, but that will not allow them to elevate their privileges in any way, if your UIs and APIs are coded securely.
PASSWORD MANAGEMENT
A stolen password is far more serious than a stolen token, since a password represents anything the user can do, possibly across many apps.
OAuth technologies keep passwords out of apps for the above reasons. Your app should never see the user's password and is not responsible for any password vulnerabilities.
Instead passwords are maintained by specialist Identity Provider software. Most commonly companies plug in a low cost cloud solution, where the password management has been developed by security experts.
Related
Every so often I hack up my own projects to solve my own problems. Sometimes I want to use data from a service. This access is often provided by oauth.
oAuth solves a more general problem than I want to solve. It lets a programmer request that a user provides data via a website. In my case I am the user and the programmer, and I don't really want to implement the website.
Is there an easy way for me to grant myself access to my own data without writing a website?
Resources
This diagram from this blog post [http://www.bubblecode.net/en/2016/01/22/understanding-oauth2/] gives a good overview of oauth.
Only if I understand your flow correctly, I think you should use the password grant type (see here).
Because you use google authentication server (google account) and resource server (e.g. gmail). You use the client app (maybe you write it yourself) so you sign in with username and password, so Password is your preferred grant type.
In this flow:
The resource owner password credentials (i.e., username and password) can be used directly as an authorization grant to obtain an access token.
The user’s password is accessible to the application!
Should only be used when there is a high degree of trust between the resource owner and the client (e.g., the client is part of the device operating system or a highly privileged application)
It is used for only highly-trusted clients, such as a mobile application written by the resource-server.
We have a client that among other things creates and manages Keycloak accounts.
Would it be possible for that client to retrieve tokens on behalf of the users without having to create any user passwords at all? In fact, we'd like to create user accounts and not set a password to start with. None of these users will ever authenticate themselves.
None of the oauth2 flows seem to really match this, and we were wondering if there is a variation of the password grant type in which the password is not required for trusted client ID/Secret.
Some options we explored so far are offline tokens and user impersonation, but the former requires persisting secrets, and the latter relies upon proprietary Keycloak features using cookies rather than standard OIDC.
There's as of today an experimental oauth 2 token exchange grant type available in keycloak: https://datatracker.ietf.org/doc/html/draft-ietf-oauth-token-exchange-19
As #qdivision pointed out: https://www.keycloak.org/docs/latest/securing_apps/index.html#direct-naked-impersonation
And Thomas Darimont: https://blog.softwaremill.com/who-am-i-keycloak-impersonation-api-bfe7acaf051a
What harm could a nefarious user cause if they found the client_secret?
tl;dr It is a high level security breach
If you followed recent events like Facebook breach, then we are talking the possibility of a similar threat. You are simply welcoming a malicious party to obtain access tokens, which they can used for anything.! Your OAuth token protected endpoints are now compromised.
RFC6819 - OAuth 2.0 Threat Model and Security Considerations under Threat: Obtaining Client Secrets highlights below,
The resulting impact would be the following:
Client authentication of access to the authorization server can be
bypassed.
Stolen refresh tokens or authorization "codes" can be replayed
If you are compare with a public client, which does not hold client credentials, special attack vector opens through client credentials grant. So even if refresh token or authorisation code is safe, malicious party can exploit the mentioned grant to obtain access tokens. So never ever expose client secret.
Is there any security reason why I can't set the access tokens issued through password grant to 30 days?
If it's not a bad idea, then what should I do to mitigate the situation? For example,
It could be stolen, but that's the same as your password.
I could add a GUI to allow revoking of access tokens issued to mitigate 1.
I can ensure all previous access tokens are revoked after a password change.
It is not advisable to have long lives access tokens. Yes that's because of the fact that they could be stolen.
It could be stolen, but that's the same as your password.
Stealing access token is better than stealing password. This is what OAuth 2.0 tries to solve. Usually user passwords are commonly used (ex:- Same password for Facebook and email account). Thus stealing one has more security concerns. But yet stealing an access token is bad. Limiting its lifetime is one way to mitigate the risk.
I could add a GUI to allow revoking of access tokens issued to mitigate 1.
You could, but by the time you detect this, it could be too late.! For example 30 days is lots of time and malicious party can obtain everything under it's scope.
I can ensure all previous access tokens are revoked after a password change.
By default this must be done.! So this is not a solution for your scenario but a standard practice.
A solution ?
Use refresh tokens to refresh expired access tokens. Usually refresh token has an extended life-time. Unlike access token, you will use it rarely thus if you store it securely, you can protect it. Also, if your client is of type confidential, then you add another level of protection. So short lived access tokens and long lived refresh tokens is a better solution.
Is there any way that a third-party app can logically use Touch ID to authenticate to a web service that uses OAuth2?
Say I own a web service that requires authentication using OAuth2. It supports both the implicit and authorization-code grants (although I could add support for other grants if necessary).
A third party has a mobile app that uses this web service. It opens a native web view to authenticate, and loads my auth URL in it. The user enters their username/password on my domain, and I return an OAuth token back to the app.
If this app wants to implement Touch ID to speed up authentication, is there a way to do it that makes sense with OAuth2?
My understanding is that the purpose of the OAuth2 implicit and auth-code grants is to prevent the parent app from having access to the user's credentials. It only gets access to the resulting OAuth token, and that's only valid for a limited time.
With Touch ID, you would typically store the password using Keychain Services. So this obviously requires you to have access to the password.
I suppose they could store the OAuth token in the keychain instead of the password, but then this would only be valid for a short time.
The only answer I've come up with so far is what you allude to at the end: store the OAuth tokens -- but also a long-lived refresh token. How long that refresh token can live is definitely dependent on your specific security needs.
I don't know about any standard flow yet but here are some common considerations. Simply storing long-term credentials (passwords or refresh tokens, even encrypted at rest) would be mixing up security contexts in a way that is hard to audit. When using any local authentication (app-specific unlock PIN, any biometrics, or simply system unlock) it's important to do it in a way that can be verified by the server. So the first step would be device authentication, every instance of your app should use unique client id/client credentials (I suggest to implement Dynamic Client Registration Protocol to help with that but there could be other options). Then, it's a good idea to generate some piece of verifiable key information directly on the device, put it into secure storage (protected by whatever local unlocking mechanism and invalidated whenever biometrics changes or) and use it to generate a MAC of some kind, for example a JWT as a part of jwt-bearer flow (or some new extension to OAuth assertion framework). JWT tokens could include additional metadata (claims) that can provide more context to the server, like it can make informed decisions to force re-authentication in some cases.
To restate:
Device is authorized and issued an unique client credentials pair.
Locally-generated key is saved to the encrypted storage and protected by some local unlock mechanism (system lockscreen, PIN, biometrics, etc.)
The key gets registered with the server and tied to the device.
On unlocking the key is used to generate a JWT that is used as assertion for authenticating with the server.
Seems pretty standard to me, maybe someone should write up a BCP for this after thinking through all the implementation details, current practice, and security considerations.