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.
Related
Currently building up a microservice for handling auth-related stuff using OIDC.
Now, we think about access control and how to be as future-proof as possible. This auth server is only used for first-party applications (3x SPA, 2x native mobile App). On mobile, we use the authorization_code grant. Each resource server validates the supplied token (access token as JWT) itself. But what happens when (in future), we add a service which needs its own scope to check (e.g. notifications:read)? As mobile app users are not used to logging in and out everytime (when we would update the requested scopes via an app update -> bad solution) is there any sweet solution to manage this scenario?
Per specification, it's possible to change the required scopes when refreshing a token but this is limited to require less scopes than originally requested and not more so that's not an option.
For example, Facebook is providing only four scopes for Instagram e.g. instagram_basic or instagram_content_publish. Zalando for example includes only a scope NORMAL_USER in their tokens whereas Wolt includes the users roles as a claim.
I think there is some confusion as this scenario is not covered directly by OAuth2 or OIDC. What are your thoughts about this?
There is one standard for doing OAuth 2.0 Incremental Authorization, but your challenge is to find a token provider that supports it or similar standards.
In a micro service architecture, the question is if you should use the access token from the authorization code flow everywhere, or if for service-to-service communication, you should use client credentials flow instead.
See also https://www.gmass.co/blog/oauth-incremental-authorization-is-useless/
It seems like you could use Token Exchange for that.
For example it could work like that - whenever your resource server gets a token without the notifications:read scope, issued before date x (so before you were issuing that scope) it performs an exchange with the authorization server and (if the server decides that it can perform the exchange) it gets a new access token that contains that scope. If the token was issued after date x you can safely assume that the token was not granted this scope.
Another solution would be to use claims for authorization decisions instead of scopes. The authorization server can issue e.g. a claim notifications_read: true, or something like that. Whenever you refresh tokens you can issue more claims in the new access token, the spec does not prevent that. Then your resource servers should check claims in the access token, they can ignore scopes. The resource server would just check whether the token contains the notifications_read claim with value true, or not. This solution gets a bit more complicated if you require your users to give consent to scopes, but as you said you're using this only for 1st-party, so I assume you're not using consent screens.
You can have a look at this free course - this topic of using claims in authorization is covered in part 4.
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.
I am using spring oauth2 for generating bearer tokens and validating them. I store tokens in database. I would like to know that is there any facility provided by spring oauth2 to cache the token as it is costly to go to db and fetch the token for validation when the servers are hit by 100tps.
I get that this is old but for the benefit of others.
Try not to store tokens anywhere unless you need the facility to revoke them. If you are committed to not storing them, that by default means you are (or should) be using JWT formatted tokens.
Spring, by default, includes user data in the bearer access JWT token that is produced.
Therefore your client / resource server that is a recipient of the JWT token has enough knowledge to automatically create an authentication object and manage access to resources.
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.
I am learning oAuth2 for the first time. I am going to use it to provide authentication for some simple web services using a two-legged approach.
According to what I have read, the flow should go like this: the web service client supplies some kind of credential to the oAuth server (I'm thinking of using JWT). If the credentials are valid, the oAuth server returns an access token. The web service client then supplies the access token when attempting to use the web service end point.
Here is my question, why not just supply the JWT when making a request to the end point? Why is oAuth's flow conceived this way. Why not just supply to JTW to the end point and use that for authentication? What is the advantage of having the extra step of getting an access token?
Thanks!
You can certainly supply the JWT directly to the web service. The questions is how do you generate it in a way that the service trusts.
A JWT is and access_token, but not all access_tokens are JWTs.
Your client can issue a JWT, sign it with a key (or a cert) and then send it to the API. The advantage of having a 3rd party (an Issuer) is that you can separate authentication from issuing tokens. Clients can authenticate in multiple ways (e.g. usr/pwd, certs, keys, whatever) and then use the JWT to call your API.
The additional abstraction gives you more flexibility and management scalability. For example: if you have 1 consumer of your API, then you are probably ok with a single credential (or JWT, or whatever). If you plan your APIs to be consumed by many clients, then handing that responsibility to a specialized component (e.g. the the issuer) makes more sense.
OAuth BTW, was designed for a specific use case: delegate access to an API to another system on your behalf. You grant access to system-A to access resources on system-B on your behalf with a permission scope.