We have an OAuth server that uses doorkeeper. We want to start using doorkeeper JWT, but we can't turn it on for all OAuth clients yet as some are out of our control and we are pretty sure they are storing the access tokens their apps receive in a varchar(255) column which won't work if we start to hand out JWT tokens for all apps. Also, we don't really want to be storing the whole JWT in our database either if we can avoid it.
Our idea is to have doorkeeper generate an opaque access token for all apps first, and store that in the db. Then before returning the opaque access token to the app, we check to see if the app has JWT tokens turned on and if so convert the opaque access token to a JWT access token using the opaque access token as the JWT's jti claim. We are thinking of utilizing the before_successful_strategy_response callback to convert to a JWT using the gem 'doorkeeper-jwt' if the app has JWT access tokens enabled.
Then, when we get a request which has an access token, check to see if the access token is a JWT access token and if so read the jti claim out of it and use that to load the access token from the DB. We don't have a good place to hook into this at the moment. Right now we are thinking of monkey patching Doorkeeper::Oauth::Token in the from_request method to check to see if the token is a JWT before returning it, and if so, return the JWTs jti instead.
Does that seem like a reasonable approach? Is there another way without monkey patching Doorkeeper::Oauth::Token?
More recent versions of doorkeeper allow you to configure the access token model class as seen here:
https://github.com/doorkeeper-gem/doorkeeper/blob/55488ccd9910e0c45ed4342617da8e026f4f55b5/lib/doorkeeper/oauth/token.rb#L17
So we can hook into the access token lookup there without resorting to monkey patching.
Related
There is a lot of information on OAuth, OIDC and Keycloak, but the main thing every tutorial seems to gloss over is offline validation. The only information I found is in the Keycloak docs on RPT introspection:
No. Just like a regular access token issued by a Keycloak server, RPTs also use the JSON web token (JWT) specification as the default format. If you want to validate these tokens without a call to the remote introspection endpoint, you can decode the RPT and query for its validity locally. Once you decode the token, you can also use the permissions within the token to enforce authorization decisions.
If I wanted to verify a user's request with an authorization token, I would make a request to the Keycloak introspection (or userinfo?) API. I'm not completely sure, but I would guess that Keycloak then verifies the info encoded in the JWT with the Keycloak user database.
However, what if I don't want to make a Keycloak request on every API request? This could improve system performance by limiting the amount of HTTP requests. There are mentions of JWT signature validations and reading the scope and user information encoded in the JWT, but I don't see how this guarantees safety. Isn't it possible to just generate any old JWT, encode any information you want and basically spoof an authorization token? How would I check if the user mentioned in the JWT really exists in the Keycloak database?
I think I am missing some crucial part of this technology.
For example, in ASP.NET Core, an API that receives a JWT token will, at startup, download the public signing keys from the token provider, and by default, it will refresh the keys every 24 hours.
So, when the API receives a JWT token, it will do various checks to validate the token, including:
Validating the signature using the provider public signing key
Validate the audience claim (is the token intended for me?)
Validate the expiry date
The API should not need to query anything against the token provider (keycloak) to let the user in.
However, then we have authorization (What the user is allowed to do), which is a different thing, and that all depends on your requirements.
JWT is all about who the user is; if the token is valid, you can trust that information.
With JWT-tokens, your API can work almost offline from the token provider. It can even be 100% disconnected if you copy the public signing key manually into the API.
I m using a client credential flow to access the API. I am getting the access token each time client make a call to Web API which seem to me may not be good but not sure why. I looked through web I am getting mix answer, some say Client Credential flow doesn't return refresh token some say possible but it is not clear how. I looked at the project where it seem to store the token in the cache but doesn't show how it can be use when needing to get the access token.
Even if Client Credential flow doesn't support or send refresh token. I am searching for a way to store the access token and use it until is is not expired and get a new one when it is expire. This is where I am looking for support.
Beside that I do have relevant question.
Should I just get the access token each time? what is the downfall of it?
Should I include a Test method is Web Api to validate if the token is expired and return "Unauthorize" response based on that response I get the new token? With this approach, I will calling the API each time I need to access the API for actual purpose. So wouldn't I just get the access token from the Authorization server (Microsoft Identity platform).
Have a look at these resources:
https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki/Client-credential-flows
https://learn.microsoft.com/en-us/azure/active-directory/develop/msal-net-token-cache-serialization?tabs=aspnet
One possible solution is to implement internally your own solution:
Get the Token.
A Dictionary is going to hold the (API type) as a key and the corresponding token as its value.
Next call check if the token exists in your Dic(TryGetValu(ket, out param)).
Check "ExpiresOn" on the AuthenticationResult (the Token) and compare its time for validation.
Remember to maintain your Dic by Updating or adding new tokens.
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 am developing an OAuth2.0 Server. What should be the format of refresh token and what encryption algo should be used for encryption?
OAuth 2.0 does not enforce any restrictions regarding token formats or encryption. Encryption is completely disregarded in the spec, as communication is supposed to be secured with TLS.
Also - don't implement yourself if you don't really have to. Choose an open source library or even a vendor product if your funding permits it.
That being said, take a look at the JWT RFC. That's the format most people use. You can also consider no format at all and just work with opaque strings, and then implement token introspection in your Authorization server.
As to encryption - anything goes. Most implementations out there support at the very least HS256, RS256 and ES256 for signing JWT tokens. In most real world scenarios you don't need to encrypt the token, a signature is enough.
After struggling for sometime, I figured it out. There are two approaches
Either put everything that you need to construct access token (apart from things that can be derived/calculated directly) in refresh token and encrypt it with global or tenant level symmetric key
Benefits:
a. No storage required
b. Better performance as No contact with DB is required. It is just decryption and creation of access token
Issues/shortcomings
a. No way to keep track of refresh tokens issued.
b. No way to invalidate the issued refresh tokens.
Storing attributes related to refresh token in DB and in response of OAuth Server, returning encrypted refresh token ID. Attributes that might be stored in DB are
ID || Expiry || Count of Token || Subject || Client ID || Custom Attributes (If required)
There can be other attributes as well which we implemented but this must give a bit of idea to people who want to implement their own Refresh Token flow
I'm using dotnetopenauth 3.4.7.11121.
I need to generate an access token for an application(it will supply its id and secret), not for a user, somenthing like what Facebook does.
Is it possible using 3.4.7.11121?
I guess I need somenthing like this scenario
It sounds like you're talking about OAuth 1.0. Based on that assumption...
Just come up with an access token and token secret yourself, store it in your OAuth 1.0 service provider's token database, and give it to your OAuth 1.0 consumer. When the call to service provider comes in, DNOA will validate the token against your access token database and it will show up as valid.
In other words, if you want a non-standard way of issuing OAuth 1.0 access tokens, just do it yourself -- not need to use DotNetOpenAuth for generating the access token as it is just a series of random characters stored in a database table.