Does an OAuth Consumer validate a bearer token with the OAuth provider on each request - ruby-on-rails

To learn more about OAuth, I'm trying to write an OAuth 2.0 provider and also a consumer.
I'm kind of using the Doorkeeper Gem as a reference for my provider, but I'd like to write my own.
My question is about the last bullet in Section 1.3 of the spec regarding bearer tokens.
(F) The resource server validates the access token, and if valid,
serves the request.
In this scenario, does The resource server validates the access token mean that it:
checks the access token against its own locally stored copy of the access token and its expiry
makes a request to the provider server, which returns a response of valid/not valid?
does something else entirely

The specification does not answer that question, because it is an implementation detail that has no effect on the working of the protocol. Nevertheless, it is a good question that can have an impact on security.
First of all, you have to realize that in some implementations, the resource server and the authorization server are just two roles of one single entity.
As the OAuth 2.0 specification (RFC 6749) puts it:
The interaction between the authorization server and resource server
is beyond the scope of this specification. The authorization server
may be the same server as the resource server or a separate entity.
They may both be present in a single web site. Maybe they are two different web sites, but they both do have a connection to the same database. The resource server can then lookup the token in the database, just as well as the authorization server can.
If the resource server cannot read the authorization server's database, than it has to talk to the authorization server (and even if it can, it would probably be a good idea to not read the database directly).
How exactly you establish and secure that communication is up to you, but an HTTPS REST request makes a lot of sense. Many implementation have different mechanisms. For examples, see OAuth-2.0 resource servers token validation in distributed environment.
UPDATE: the standard way for a resource server to validate a token is now OAuth 2.0 Token Introspection (RFC 7662).
Obviously, when an access token is presented to a resource server for the first time, the resource server does not know about it, and has to access the authorization server to check for validity. The interesting question now is: can the resource server cache this response, or does it have to make the call on every request?
That is a design decision to be made by the resource server, and it may be influenced by many different factors. For example:
If the authorization server responds very quickly, there may be no need for the resource server to cache the response. In fact, a badly designed cache may be slower than not caching.
The need to design and implement a cache with a good cache policy may be prohibitive for implementing a good cache in the resource server.
Depending on the nature and the scale of the resource server, the cost of allocating RAM or storage on disk to a cache may be prohibitive for implementing a good cache in the resource server. This is especially true when the number of access tokens out there is very high, and a lot of storage is required to obtain a sensible cache hit ratio.
Is the resource server prepared to accept an access token, even if it has been revoked in the authorization server?
That last point deserves some further explanation. The authorization server typically has several mechanisms to revoke tokens. If a resource owner revokes an authorization through the UI, the authorization server has to invalidate all tokens obtained through that authorization (access tokens and refresh tokens). The resource server may also implement a token revoke endpoint (often used for a "log-out" mechanism in public clients that use the implicit grant).
Is the resource server prepared to take the risk of accepting a token, even after it has been revoked? And if so, for how long? If it is, then it can cache the token, otherwise it can not. At first sight, you would of course say that a resource server SHOULD NOT use cached token validation responses. But in some cases there might be performance advantages that outweigh the risk. It obviously also depends on the nature of the resources stored by the resource server, and the real risks associated with them.
Again, this is a design decision we can not make for you. From a security perspective, you should not cache validation responses in the resource server.

Related

spring oauth2: resource server without authorization server

I need some lights about convenience of using an autheorizarion server in my project scope.
We're realising and deploying our services into customer environment.
Customer infrastructure already provides an authentication mechanism in order to authenticate users.
This mechanism intercepts all comunications and redirects user to a "login" form.
After that, user is redirected to our service and we've to handle and digest it and respond with an JWT token.
Here is where I'm feeling lost:
I'm thinking about:
using spring-oauth2 in order to request a JWT token to an authorization server, or
using spring-oauth2 in order to auto-generate an JWT token and validate it. I don't know if it's possible.
My question is, since user is already authenticated, have it sense to use an oauth2 authorization server, using client-credentials in order to authentication client against our resource services?
Short question would be, could I use spring-oauth2 librearies in order to generate a JWT without an authorization server?
You technically can do it, but I would discourage you from doing that. Access tokens in a system should be issued centrally, by a dedicated service. Otherwise, it will be hard to maintain the infrastructure. If your services will start to issue JWTs, then they will also have to provide the public keys for others to validate these JWTs. Keys management, access token contents management, and any rules of mapping user information into claims - will now become part of your service and it will unnecessarily complicate its implementation.
If the customer's authentication mechanism issues a JWT, why not use that one for request authorization? If that one is insufficient, I would recommend having an Authorization Server (or a dedicated service), that can perform Token Exchange and exchange the original JWT for a new one.

How can I restrict access to my rest API?

I'm developing my very first mobile application and I need advice. I created REST API in spring boot and it works great but I want to restrict access. It should be used only by my app. There is no user login it only gets data from the server.
Would be some API token enough or is there any other way how can I do this?
maybe it's a stupid question but I really need advice.
thanks
You can use these pointers -
Least Privilege:
An entity should only have the required set of permissions to perform the actions for which they are authorized, and no more. Permissions can be added as needed and should be revoked when no longer in use.
Fail-Safe Defaults:
A user’s default access level to any resource in the system should be “denied” unless they’ve been granted a “permit” explicitly.
Economy of Mechanism:
The design should be as simple as possible. All the component interfaces and the interactions between them should be simple enough to understand.
Complete Mediation:
A system should validate access rights to all its resources to ensure that they’re allowed and should not rely on the cached permission matrix. If the access level to a given resource is being revoked, but that isn’t reflected in the permission matrix, it would violate the security.
Open Design:
This principle highlights the importance of building a system in an open manner—with no secret, confidential algorithms.
Separation of Privilege:
Granting permissions to an entity should not be purely based on a single condition, a combination of conditions based on the type of resource is a better idea.
Least Common Mechanism:
It concerns the risk of sharing state among different components. If one can corrupt the shared state, it can then corrupt all the other components that depend on it.
Psychological Acceptability:
It states that security mechanisms should not make the resource more difficult to access than if the security mechanisms were not present. In short, security should not make worse the user experience.
Always Use HTTPS (This is hard)
By always using SSL, the authentication credentials can be simplified to a randomly generated access token that is delivered in the username field of HTTP Basic Auth. It’s relatively simple to use, and you get a lot of security features for free.
If you use HTTP 2, to improve performance – you can even send multiple requests over a single connection, that way you avoid the complete TCP and SSL handshake overhead on later requests.
Use Password Hash
Passwords must always be hashed to protect the system (or minimize the damage) even if it is compromised in some hacking attempts. There are many such hashing algorithms which can prove really effective for password security e.g. PBKDF2, bcrypt and scrypt algorithms.
Never expose information on URLs
Usernames, passwords, session tokens, and API keys should not appear in the URL, as this can be captured in web server logs, which makes them easily exploitable.
https://api.domain.com/user-management/users/{id}/someAction?apiKey=abcd123456789 //Very BAD !!
The above URL exposes the API key. So, never use this form of security.
Consider OAuth
Though basic auth is good enough for most of the APIs and if implemented correctly, it’s secure as well – yet you may want to consider OAuth as well. The OAuth 2.0 authorization framework enables a third-party application to obtain limited access to an HTTP service, either on behalf of a resource owner by orchestrating an approval interaction between the resource owner and the HTTP service, or by allowing the third-party application to obtain access on its own behalf.
Consider Adding Timestamp in Request
Along with other request parameters, you may add a request timestamp as an HTTP custom header in API requests. The server will compare the current timestamp to the request timestamp and only accepts the request if it is within a reasonable timeframe (1-2 minutes, perhaps).
This will prevent very basic replay attacks from people who are trying to brute force your system without changing this timestamp.
Input Parameter Validation
Validate request parameters on the very first step, before it reaches to application logic. Put strong validation checks and reject the request immediately if validation fails. In API response, send relevant error messages and examples of correct input format to improve user experience.
You can use this as a checklist while making a rest API

Is Basic Authorization fine in machine to machine communication compared to OAuth2

Introduction
So in my developer team, we need two server-based applications one located in my company architecture let's call it company server (i.e. resource and authorization server in OAuth2 terminology) and the second one in customer architecture let's call it customer server (i.e client and resource owner). The customer server is loading data from the company server so my company server needs to authenticate it somehow.
My team decides to apply OAuth2 standard with authorization and resource server in a single monolith application, without even thinking of benefits. This would, of course, take more time to implement than a simple constant key stored in the header. So I wonder what are benefits of that solution.
I know that Basic Authentication needs user:password base64-encoded in every request but the customer server is a single user so token would be in fact constant key stored in the header and I will use that terminology in terms of simplicity.
Argument - Microservices
In M2M (machine-to-machine) communication according to this article, customer server should obtain the token by providing client_id and client_secret from authorization server then you can use with multiple resource servers. The first argument I see is that OAuth2 pattern allows us to use multiple resource servers without additionally reimplementing authorization in each of them (because token is JWT or resource server is checking token against authorization) but in our case we have only one monolithic company server that is responsible for being resource and authorization so I see no benefits of that.
Argument - Man-in-the-middle protection
The other argument of using OAuth2 is protection against man-in-the-middle attack if someone intercepts token. The authorization server can invalidate token (directly in storage or in case of signed JWT by short expiry time) and prevent using compromised token. But...
Connection between servers is SSL secured
There's no way to steal token from storage like in a web-based or mobile-based application because key is located on the server-side itself.
Summary
So I can't think of any security benefits using OAuth2 compared to using the constant key in every request in this situation.
Security is mostly a chicken-egg problem. You encrypt secrets with encryption key and then again you think how do we handle the encryption key in a secured way. Don't assume here that TLS/SSL is infallible. But the core objective has always been to reduce the attack surface and make it more difficult for malicious users to break the system.
Even when there is no "Man in the Middle", when you send the password with every request, both the receiving side and the sending side keep the password in memory. It leaves more opportunity for an attacker to get hold of the password. A simple memory dump can expose the password.
In case of tokens, you don't always need the private key in memory to verify the token signature. You can cache the valid tokens at the server end and simply do a string match. Or you can use a public private key pair.
So, it's okay not to use OAuth2, if the security requirements are not stringent enough to justify the development effort required for a more secured solution. But it is better to use proven best practices and solutions.

Is it OK for an OAuth client to determine the access_token server side and then pass the token to the browser?

I can find plenty of example of single page apps (which can't manage a client secret) and plenty of examples of old-school server-side apps (which can manage a client secret) using OAuth.
But for us and, I suspect, the majority of enterprisey systems, a system is both server-based and client-based.
We can easily (and securely) identify the client server-side, and we could then make the resulting (user) access_token available browser-side.
The question is, does doing this introduce a risk?
The client-server (the server-side component of the client) cannot guarantee that the browser is running its code - but it can guarantee that all access to the resource owner's data on the client has been approved by the resource owner.
Thanks.
The principle itself does not introduce a risk but of course you need to take care of the method used to expose the access token to the browser. One such approach is documented here: https://hanszandbelt.wordpress.com/2017/02/24/openid-connect-for-single-page-applications/
It suggests to expose a server-side endpoint that can be called with a cookie which will then return session information that may include the access token.

May an OAuth 2.0 access token be a JWT?

From what I can tell, the OAuth 2.0 specification is extremely vague in terms of what form an access token should take:
The token may denote an identifier used to retrieve the authorization
information or may self-contain the authorization information in a verifiable manner (i.e., a token string consisting of some data and a signature). Additional authentication credentials, which are beyond the scope of this specification, may be required in order for the client to use a token.
The access token provides an abstraction layer, replacing different authorization constructs (e.g., username and password) with a single token understood by the resource server. This abstraction enables issuing access tokens more restrictive than the authorization grant used to obtain them, as well as removing the resource server's need to understand a wide range of authentication methods.
Access tokens can have different formats, structures, and methods of utilization (e.g., cryptographic properties) based on the resource server security requirements. Access token attributes and the methods used to access protected resources are beyond the scope of this specification and are defined by companion specifications such as RFC6750.
(emphasis added)
The linked RFC6750 doesn't offer much further specificity. There is an example HTTP response body that shows:
{
"access_token":"mF_9.B5f-4.1JqM",
"token_type":"Bearer",
"expires_in":3600,
"refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA"
}
This seems to indicate that the access_token can be opaque ASCII text such as an encoded JSON Web Token (JWT)
From my perspective, it seems like JWT-as-access_token has some desirable properties:
It's a known specification, with fairly wide adoption and client libraries available in many languages.
It allows for easy signing and verification using vetted cryptographic libraries.
Because it can be decoded to JSON, it would allow us to include metadata and information about the token within the token itself.
My questions are: First, is it permissible for the access token to be a JWT? Second, if it is permissible according to the spec, are there any additional considerations that would make using a JWT as an access token a bad idea?
A1: Using a JWT as an access token is certainly permissible by spec exactly because the spec does not restrict its format.
A2: The idea behind using a JWT as an access token is that it can then be self-contained so that the target can verify the access token and use the associated content without having to go back to the Authorization Server. That is a great property but makes revocation harder. So if your system requires a capability for immediate revocation of access, a JWT is probably not the right choice for an access token (though you can get pretty far by reducing the lifetime of the JWT).
As long as the Authorization Server and the Resource Server agree on what the access token means, it doesn't matter what their content is. So the only reason you could have a problem would be if you were using different libraries or frameworks when implementing those two servers.
Currently the OAuth Working Group is working on a JWT profile for OAuth 2.0 access tokens: JSON Web Token (JWT) Profile for OAuth 2.0 Access Tokens

Resources