OAuth v2 communication between authentication and resource server - web-services

I'm having some troubles understanding how OAUTH-v2 works.
The OAuth version 2 spec reads:
Accessing Protected Resources
The client accesses protected
resources by presenting the access
token to the resource server. The
resource server MUST validate the
access token and ensure it has not
expired and that its scope covers
the requested resource. The methods
used by the resource server to
validate the access token (as well as
any error responses) are beyond the
scope of this specification, but
generally involve an interaction or
coordination between the resource
server and the authorization
server.
How does this interaction between resource server and authorization server work in practice?
How does the resource server
determine that an access token it
received is valid?
How does the
resource server extract the allowed
scope from the token to see if access should be granted to a particular resource? Is the Scope encoded in the access token, or does the resource server first have to contact the authorization server?
How is trust between the resource server and the authorization server established?
Access token attributes and the
methods used to access protected
resources are beyond the scope of this
specification and are defined by
companion specifications.
Can someone give examples for token attributes?

The reason this is out of scope for the specification is the wide range of ways to accomplish this connection between the two entities. The main question is how complex is your deployment.
For example, do you have one server managing authentication and access, and a set of discrete services each with its own servers serving the API calls? Or, do you have just one box with one web server which handles both authentication/authorization and the API calls?
In the case of a single box, not much is needed as the entity issuing tokens is the same as the one validating them. You can implement tokens to use a database table key and lookup the record in the database (or memory cache) on every request, or you can encode the scope, user id and other information directly into the token and encrypt it using a symmetric or asymmetric algorithm.
Things get a bit more complex when dealing with a distributed environment, but not by much. You still issue tokens at the authorization server, but the resource server needs a way to validate those. It can do it by making an internal API available to the resource server to ask the authorization server to "resolve" the token (which can be fast in a local environment), or the two can establish a public/private key pair or symmetric secret and use that to encrypt everything the resource server needs into the token.
Self contained tokens are longer but offer much better performance per-request. However, they come with a price - you can't really revoke them while they are still valid (not expired). For this reason, self contained tokens should be very short lived (whatever is acceptable to you to leave access open after it was revoked - e.g. many sites use one hour), with a refresh token good for a year or more to get new tokens.

One example of resource- to authorization server API is the one at Google Developers Website.
It doesn't specify the format of the access token though, but the response seems pretty universally useful.

Related

Is it a good praxis to secure an webservice endpoint with a simple token string?

I have a web application where the regular user login is handled via SSO.(This prevents me from creating a service user)
In this application I have some web service endpoints that are not in the scope of any user. They will be triggered by another application and do some stuff.
Is the following the right way to do.
A token string is created by hand(because of simplicity)
The token string is stored in the environment variables of the system that provides the webservice endpoint as well as in the system that calls those endpoints.
On every call a simple equality check is proceeded - if the token is not present, the endpoint returns a 401.
Is my approach to simple?
I have not found much on this topic - my approach comes from the moodle-webservice handling, where you generate a webservice token in moodle and place it aswell in the application that calls the webservice.
For a basic application with no high security requirements, this might be ok.
A few things you could do (all of which will increase complexity and/or cost):
The service could store a proper password hash (like bcrypt, pbkdf2 or argon2) instead of the actual password. This would help, because if it is compromised, the actual key would not be lost, the attacker could still not easily call the service. (But it's already compromised, and this is not like a user password that would be reused, so it depends your choices and threat model.)
You could store this secret in a proper vault like AWS Secrets Manager or Hashicorp Vault or similar. This would enable you to control access to the key in one place, and audit key usage (maybe alert on attempts and so on). Access to the vault would still have to be managed, but that's easy via roles on AWS for example, where instances with the right role can access the secret but others cannot.

Passing Google access token from client to server

I have an application integrated with Google services (Google Bigquery API to be specific.)
I am authenticating the user on the client side, without offline access scopes (hence without refresh tokens), and doing most of the operations on the client side. But there are some operations I want to do on the server side (still on the authenticated user's behalf.)
Currently, I am passing access tokens to the server side (over https), initializing Google libraries on the server side with this token, and doing the operations there.
The documentations I've found on Google regarding this are either using authentication on the server side, with refresh tokens or completely on the client side. Could not find a documentation suggesting best practices for this mixed case.
In short, what I want to do is, using short lived access tokens acquired on the client side on the backend.
Are there any security risks with this approach? And regardless of that, is this the suggested way of doing what I want?
Regardless of BigQuery oAuth2 implementation, the market general security best practice is to store ONLY short term Security Token on the client side. Even that might be a challenge depending on your client security technique and framework.
Two important points from the official OAuth 2.0 Authorization Framework: Bearer Token Usage
Token storage
Don't store bearer tokens in cookies: Implementations MUST NOT store
bearer tokens within cookies that can be sent in the clear (which
is the default transmission mode for cookies). Implementations
that do store bearer tokens in cookies MUST take precautions
against cross-site request forgery.
Short Term Token
Issue short-lived bearer tokens: Token servers SHOULD issue
short-lived (one hour or less) bearer tokens, particularly when
issuing tokens to clients that run within a web browser or other
environments where information leakage may occur. Using
short-lived bearer tokens can reduce the impact of them being
leaked.
Now checking Bigquery documentation in this link
Their recommendation is: Save refresh tokens in secure long-term storage which are typically not done on client side storage framework.
Since you always get a refresh Token from BigQuery oAuth2 API you can use it on all your API call, done on the server side, thus giving the user a seamless secure flow. Check this in google oauthplayground
BTW: Typically doing call from the client side is for performance reasons, In BigQuery case since it's a big data solution I feel the extra few seconds involve in server-side calls are less important

JSON Web Token expiration and remember me functionality

I am starting to work on an authentication system for an angular 2 Single Page Application using django-rest framework as back-end. I'd also like to have some kind of "remember me" functionality that is going to keep users logged in for a certain amount of time.
From what I have read so far, it seems that the best authentication method for this kind of Angular 2 SPA/REST API is using jwt (json web token). For jwt authentication, I looked at the django-rest-framework-jwt (https://github.com/GetBlimp/django-rest-framework-jwt).
The problem that I see is that the token needs to have a short life span (few minutes to a few hours...) in order to minimize security issues if the token get stolen. The token now needs to be refreshed frequently to avoid the user from being disconnected while using the application. In this case, a "remember me" functionality is posing problem since the token have a short life span.
I thought about a solution involving a second token that would serve as a refresh token. It would be opaque, have a longer life span and would contain information specific to the user (ip address or something like that) so that if it get stolen, the information specific to the user being different would render this refresh token invalid.
So here are my questions:
1- I would like to know if they are existing solutions addressing this problem. As any security/authentication issues, I prefer to rely on well tested solutions to avoid getting my API compromised.
2- Would the refresh token based on specific user infos be a good idea?
3- Any other ideas how I could implement what I want?
For your situation, you really need a way to store issued tokens.
I always use an OAuth2.0 server setup that manages the auth and returns tokens the OAuth setup uses a database to manage everything so it's easy to manage and revoke tokens.
The database schema would be like this http://imgur.com/a/oRbP2 the problem with using just JWT without any management over the issued tokens with long expiration you have that security issue of not being able to revoke easily.
I would advise against including any such thing as a password in the JWT and requiring them to change it what if they use that password everywhere, then they would have to change that everywhere.
Updated from comments
Sessions Authentication use session_id which most the time is stored in a cookie and this is attached to every outgoing request. It is stateful. It is nothing more than a unique identifier that associates a user account that the server has in memory/database. For example, this can course problems when running multiple servers/instances when scaling your infrastructure.
Token Authentication no session is persisted on the server so this means it is stateless. It normally uses the header Authorization: Bearer REPLACE-WITH-TOKEN . This means that this token can be passed to multiple different servers/instances because the authentication is not limited to the server that you initiated the authentication on. This helps with scaling your infrastructure. Tokens can also be passed to other clients.
RESTful API's are stateless so there must not be a session state stored on the server. Instead, it must the handled entirely by the client so that's why token authentication is used.
I had the exact problem when trying to use JWT with an application that needed a lot more than JWT was designed for. OAuth2.0 has a lot more options that I believe are necessary to meet your requirement in the safest manner possible and even features that you may find very useful in the future as your Application may grow and need more features with regards authentication.

OAuth-2.0 resource servers token validation in distributed environment

I'm going to make a REST web service with many resource servers (implemented in different programming languages) and one authorization server.
My question is about token validation in the resource servers. Let's say that a resource server cannot connect to the database and check the token info there.
I have read this thread: OAuth v2 communication between authentication and resource server
And I like the idea to make an API in the authorization server, which will be responsible to "resolve" tokens. For example: https://oauth.example.tdl/tokeninfo?token=tokentovalidate
So my question: Should the /tokeninfo resource be "public"? I mean everyone who knows this endpoint will be able to validate tokens..
Wouldn't it be better to make this "private"? I mean https://oauth.example.tdl/tokeninfo?access_token=valid_token&token=tokentovalidate
But then my resource server will have to authorize itself before validating tokens.. too many requests, I think..
If you know more strategies to validate tokens between resource server and authorization server - tell me, because I'm pretty new to OAuth.
Should the token verification API be public?
In terms of authentication, if should of course be an authenticated API, and the access token that you use to call it is the access token you want to verify. RFC 6750 explains how to do that. Typically, the token is sent in the Authorization header, or as a Uri query parameter.
Alternatively, for more security, you require the client id and client secret to secure the call, either by passing them as parameters, either by obtaining an access token for the client using the Client Credentials Grant.
Be careful what information you return from the API. You should only return information that does not require a specific scope that has to be authorized by the resource owner.
For a real life example, see the Google implementation or the implementation from The Identity Hub. For the Facebook implementation, see the section "Confirming identity" on Manually Build a Login Flow.

End user authentication for RESTful web services

I have an internal-facing RESTful web service. There are various client applications using the service, and the client apps themselves have end users. The web service needs to authorize requests based on the end user identities.
The question: What are the typical options for authenticating the end user here? That is, I want to authenticate the user, not the client application. (I don't mind if authenticating the client application is part of the scheme, but ultimately I need to know that the end user is who I think he or she is.)
One possible scheme, for example, would be to have per-client system accounts, and then have the client simply assert the user's identity (e.g. in an HTTP request header, say). So we authenticate the client application and delegate user authentication to the client. I don't think this is a very strong scheme, though, because it depends too much on keeping the system account credentials secret. I have seen too many examples of people e-mailing system account credentials around to put much faith in this sort of approach.
Another approach might be to have the client app, upon user login, use the user's credentials to get a token from the API, and then use that token for subsequent API requests. That way the authentication is user-specific without requiring the client app to hang onto the username/password credentials.
Anyway I'd like to have a better sense for the range of options I should be considering here.
The problem that you describe with "delegated authentication" is a real one. It means that a "client application" using it's credentials has access to the whole breadth of user data. This access can be used maliciously (for example a "semi-trusted" app harvesting api data) or negligently (for example an app accidentally exposing a Direct Object Reference Vulnerability - https://www.owasp.org/index.php/Top_10_2010-A4-Insecure_Direct_Object_References)
Probably the most prevalent "token based" scheme is OAuth2 (http://oauth.net/2/), and the precursor, OAuth, which many sites choose to continue to use.
OAuth2 has a number of roles:
resource owner (the user in your case)
resource server (your api)
client (the apps you talk about)
authorization server (not clear who or what would fulfil this role in your case)
The basic scheme is that the resource owner authenticates using their credentials directly with the authorization server. They are then asked if they want to grant some information (which may just be a persistent identifier, or a description of the information exposed by your api) to some client. When they accept an 'auth code' is sent to the client and they use that (combined with their own credentials) to receive an 'access token'. This access token can then be used to authenticate against the resource server (which can check it's authenticity back against the authorization server).
Normally the way this is used is that the authorization server and the resource server are owned and managed by the same entity (for example google and facebook would fulfil this role) and then clients are independently managed.
The scheme can also be used internally within an organisation without the "explicit grant" which can still at least confirm that a specific end-user is present before releasing any data from an api.