I'm developing a REST API which uses an Access Token for verifying & validating.
There is one scenario where user can obtain the Access Token by providing proper credentials and use the same Access Token from a different machine to access any REST API.
I just wanted to check if there's any downside to allowing such a case?
Assuming we're talking OAuth 2.0: it actually depends on the access token type: a so-called Bearer access tokens can be used by any Client that gets hold of it. Bearer access tokens are used in the majority of OAuth 2.0 deployments today.
Other types of access tokens are emerging (so-called Proof of Possession tokens) that require the Client to prove that they are really the intended presenter. In that case just having the access token on a different machine is not enough. In even more advanced emerging scenario's ("token binding") the token may be bound to the TLS connection so it can never be used by another Client or on another connection.
But as said, for the majority of OAuth 2.0 deployments today, it would be possible to use the Bearer access token from another machine.
The access token should be signed by the server, and shouldn't include any information about the specific client/machine used to access it.
For example, in the OAuth 2.0 password grant flow, the username/password is exchanged for an access token. The token is signed by the issuing token server, and represents that user's authentication and authorization claims. What machine the user is making requests from makes no difference.
So, tl;dr - yes, access tokens are portable between machines. It's not a typical use case (how would the access token get from one machine to another?), but it's perfectly valid.
Related
What is best practice when it comes to AWS API Gateway Authorization via tokens? Reading mixed messages from AWS in terms of which token to use for API Gateways.
Traditionally, the Access Token is meant of API Authorization via scopes and claims on the token.
However, AWS Cognito allows little flexibility with Access Token claims.
This example on AWS: https://aws.amazon.com/blogs/security/use-amazon-cognito-to-add-claims-to-an-identity-token-for-fine-grained-authorization/ Even goes as far to us the Id Token for their Authorization. Since you can add/remove claims from the Id Token using the Pregen lambda but you can't with the Access Token.
Am I better off trying to get the Access Token to work in a more creative way for specific users than claims? Can using the Id Token like an Access Token to my API's cause any issues in the future?
Using access tokens in APIs is the standard. ID tokens do not contain scopes and do not have the correct lifetime and renewal behavior.
One of the good things about Cognito access tokens is that they do not reveal sensitive token data to internet (web and mobile) clients. This makes them a little similar to reference format access tokens.
You do not have to do JWT authorization in the gateway. In fact an emerging zero trust security model is for each API to verify the JWT itself, to prevent potential threats inside the network.
One option to extend access token claims is to validate the JWT in the API, then look up custom claims (eg from your business data), then add them to a Claims Principal used by your API's logic.
This pattern is followed in this code of mine, which uses Cognito access tokens. This adds a little complexity, but results in portable API code.
For simpler use cases, using the ID token in APIs may be sufficient and more convenient, as long as you understand the limitations.
I'm using oauth2 authorization code flow with the ASP.NET core 2.2 AddJwtBearer. My token end point returns JWT access toke with all the claims needed for checking the user's permissions.
I can send this token as the bearer for any Web API call and the standard .net code can use those claims to check permissions eg [Authorize(Policy="somePolicy")].
One of the claims points at an internal session key that we can revoke.
So my question is why would I need an ID token or even a refresh token?
The claims and other details are in the access token so what would an ID token add to this?
Having to use a further call to a userinfo end points send to be a waste if the info is in the Auth token?
If I can revoke the session that Auth token points at, surely I don't need a refresh token and can have longer life Auth tokens?
I've read lots of examples and comparisons but most computations between just oauth2 and enhanced with openid connect seem to be with very basic oauth2 not using JWT etc and so written to exaggerate the differences.
So I'm unclear when both are using the same authorization code flow and JWT tokens, what the team advantages are in using the id token in my situation??
Given your context, it seems that OpenId Connect is not necessary for your situation. It really adds value when you are implementing single sign-on (SSO). In that case the Identity token can also be used on SSO logout.
Having additional claims about the identity in the access token is also a waste. Having to send all this information on each call. Especially when you need the information only once (a Spa may persist the information in memory). It's better to have some api (endpoint) expose the information when requested.
About the access token, you can't revoke it. You may be able to revoke authorization, but the access token remains valid until it expires. You want invalid access tokens to short-circuit as soon as possible in the pipeline, before policies are evaluated.
Please note that it's not a common scenario where the api can revoke access by using an internal session key. Most api's are 'session-less' and fully rely on the access token. Because that's the purpose of a JWT, being self-contained, not having to contact the authority to verify the token.
Perhaps you can use a long-lived access token because in your situation the authorization is determined at another level. But are you capable of detecting when the token is compromised? And where are you going to check it? In every api and client? Or would you rather let the authority take care of it (single responsibility)?
When implementing security you should look at the design, the responsibilities, where to do what. Let the authority, that issues the tokens, take care of authentication and client/resource authorization. The Api, being the resource where the business rules (policies) are implemented, can take care of (user) authorization.
The problem with a long-lived token is that when it falls into the wrong hands, it allows access until it expires or, in your case, until you detect something is wrong. Where a short-lived token always allows access for a short time, making it almost not worthwhile for a hacker to obtain a token for the time it can be used.
With short-lived access tokens you'll have to use refresh tokens. The authority can verify on each call whether a new access token should be issued. Of course here counts the same, this only applies to the situation where you are actually verifying the request. Tokens in itself are not safe. You'll have to add some level of security, e.g. check the ip address. But having the authority to take care of it and using one-time-use refresh tokens already does add security.
In my experience with oidc/oauth2, the access token is mainly used to grant client applications access to a resource (on behalf of a user). Where scope claims define the accessible functionality and the sub claim identifies the user.
Authorization can be implemented on different levels and doesn't have to be part of the access token. In fact, permissions should not be part of the access token at all.
So your setup may be fine. But I wouldn't use long-lived access tokens for the reasons already mentioned. Plus they are not managable. You can't update the access token when someting changes in the flow, e.g. when a scope is added.
I am creating an API for a mobile application using Rails 5. At the moment, I don't need three-legged authorization, as the API will only be consumed by our own mobile apps.
I'm thinking of choosing one of these two options:
Doorkeeper + Devise: I can implement OAuth 2.0 using Doorkeeper, but I will only be using the Password Credentials Grant, at least for now.
Rails' own ActionController::HttpAuthentication::Token module + Devise: This seems like the simpler way to go.
Honestly, I can't see the difference between the Token Access Authentication method and OAuth 2.0's Password Credentials Grant.
How would one choose one over the other? Is there any other option that needs to be considered?
If all you'll ever have is the "single purpose API" (only for mobile application), there is no big difference in terms of security.
But if you'd like to extend this API to be used by the external services, then, you'll be in a much better position with implemented OAuth 2.0 using Doorkeeper, because you can easily configure, for example, a Authorization Code Grant for them.
So, I'd say that "Doorkeeper + Devise" option is more future-proof, because it provides more options, while HTTP Token authentication is much simpler for implementation.
The two are conceptually different things:
"Token Access Authentication" specifies a protocol describing how a (possibly long-lived) token should be presented to the server securely. It says nothing about where the token came from or how it should be interpreted.
"Password Credentials Grant" is a part of the fully-fledged OAuth flow, describing the means of obtaining a (usually short-lived) token.
In a sense, you could use Password Credentials Grant to obtain a token using OAuth and then use this token in the Token authorization header to gain access.
The question then becomes - is it useful to do the extra roundtrip for exchanging the (permanent and secret) credentials for a (temporary) token, when we could instead use the (permanent and secret) token stored in the app to authorize immediately anyway.
As I see it, there are two potential benefits of using the full OAuth flow. Firstly, it lets you add other means of authorization for third parties naturally. Secondly, it lets you revoke the token at any moment and force a re-authorization using these other means (if you implement them, of course) without having to invent any wheels.
On the other hand, you can always add any additional "token generation" parts later, when they are needed. Thus, if your current plan is to hard-code credentials in code anyway, I'd suspect you are probably better off relying on Token authorization.
Not only is it one request shorter, it may also be slightly more secure than the Bearer authentication used in OAuth: if an attacker sniffs a Bearer token, they would (usually) get full token access to the server until its expiration. It is not the case with Token tokens (normally). Not that it all matters too much of course if the attacker could extract the shared secret from your app anyway.
I have very little experience with Oauth 2.0 and am trying to better understand how the system works. Are access tokens tied to a user/device/session? For example, can I migrate an access token granted for one app and use it in another app? How will the server/API know? I believe most APIs have apps request using an app_ID, is there any other data that goes into a request for a token?
Thanks!
The OAuth 2.0 protocol framework is designed to allow for different types of access tokens but the only access token that has been standardized so far is the so-called "Bearer" token, so I'm assuming your question is about that.
A Bearer token is opaque to the Client which means that it is just an "identifier" or "string" that the Client passes on to the Resource Server to get access to protected resources. This also means that it is not specifically tied to a device/session or Client. In fact anyone who gets a hold of the Bearer token can actually use it to get access to the protected resources. This is one of the known drawbacks of Bearer tokens but it makes it very easy to implement them. It relies on a secure HTTPs channel for confidentiality.
The previous paragraph describes how to use a Bearer token. The process that the Client has to go through to obtain such a token, may include presenting a Client identifier and a Client secret to the Authorization Server indeed. But the Resource Server (aka. Server or API) does not know or care how the Client obtained the Bearer token.
There are token extensions of OAuth 2.0 under development that would require the Client to proof that it is the rightful owner of the token. Such tokens are called "Proof of Possession" Tokens and may be useful in environments that have higher security requirements. See: http://www.thread-safe.com/2015/01/proof-of-possession-putting-pieces.html
Can't the server just "upgrade" the temporary credentials to token credentials and retain the same key and secret?
The client can then start doing authenticated calls right away after the recieving the callback from the server stating that the temporary credentials has been "upgraded".
Of cause if the temporary credentials have not be upgrade (i.e. client doesn't wait for callback) the authenticated call fails.
So the question is why make an extra call to the server after the callback to "exchange" temporary credentials for token credentials?
You could implement OAuth in that way, but as I understand it, separating Request Tokens from Access Tokens does provide an extra layer of security.
From the Beginner's Guide:
OAuth includes two kind of Tokens:
Request Token and Access Token. Each
Token has a very specific role in the
OAuth delegation workflow. While
mostly an artifact of how the OAuth
specification evolved, the two-Token
design offers some usability and
security features which made it
worthwhile to stay in the
specification. OAuth operates on two
channels: a front-channel which is
used to engage the User and request
authorization, and a back-channel used
by the Consumer to directly interact
with the Service Provider. By limiting
the Access Token to the back-channel,
the Token itself remains concealed
from the User. This allows the Access
Token to carry special meanings and to
have a larger size than the
front-channel Request Token which is
exposed to the User when requesting
authorization, and in some cases needs
to be manually entered (mobile device
or set-top box).
So, as I understand it, by limiting the Access Token to a channel directly between the consumer (your service) and the provider (the service you're gaining access to), you can obtain a secure Access Token (that is, one the attacker doesn't have) even if the user's machine or the user's network connection to your service is compromised. If the Request Token were simply upgraded, then anyone sniffing the user's network connection could easily obtain the Request/Access Token, which we'd prefer to keep secret since it can be used (with your consumer token, of course), potentially for a very long time, to access the user's data. A server-to-server connection is often more secure.
Also, as is pointed out above, this lets you have a much longer key in cases where the Request Token actually has to be typed out by the user (and so is probably very short).