I have been going through Doorkeeper documentation and had a look in the source code. However, I have yet to understand how Doorkeeper is generating it's tokens. The documentation is focused on how to use Doorkeeper but they don't explain how they generate the tokens and don't explain why they are using a safe token generation, verification and revocation strategy. Oauth2 is a protocol that says nothing about how to generate secured refresh tokens and access token, being Oauth2 compliant in itself says nothing about the technology used for handling token generation and verification.
May somebody explains how doorkeeper generate it's access token and refresh token, and why is it safe. How does Doorkeeper handle token revocation?
Compared to doorkeeper default token system, if all i want is to handle refresh and access token for native mobile application and I don't need the rest of Oauth2 features, would it be safer to roll my own "refresh token" strategy by using for example RSA with 1 private key per user identified externally with a uuid and storing the public key on the server and use ssh style encryption challenge over an API, or use JWT with RS512 and use the public key to verify the signature of the token to authenticate the user. The revocation in both cases would be handled by whitelisting the public keys.
My question is not about the OAuth2 protocol that I understand or a statement about the security of doorkeeper but state my ignorance of how doorkeeper handle its tokens, I know it is not a good idea to reinvent the wheel, at the same time I don't want to use something I don't understand, and I don't understand how doorkeeper handle tokens.
Here is an explanation of the main parts, along with pointers to code, for Doorkeeper version v5.2.3
.
By default, Doorkeeper provides a way to specify the TokenGenerator
.
If the TokenGenerator
is not specified the default one is Doorkeeper::OAuth::Helpers::UniqueToken
.
The UniqueToken
generator is using SecureRandom
(provided by the Ruby standard library) to generate a token using the .urlsafe_base64
method as specified in RFC6750. Practically, you can consider SecureRandomn.urlsafe_base64
secure enough for all intents and purposes.
Doorkeeper stores the access tokens in the database and is using ActiveRecord (from Rails) as an ORM. Before creating a Doorkeeper::AccessToken
entry in the database it calls the #generate_token
method. The #generate_token
method is provided by the AccessTokenMixin
mix-in which is included in Doorkeeper::AccessToken
model.
The sequence is:
Doorkeeper::AccessToken
will be createdAccessTokenMixin#generate_token
method is called (before
callback)#token_generator
method is calledUniqueToken
token generator is returned#generate_token
the token_generator#generate
method is calledSecureRandom
#generate_token
the secret can be encrypted using bcrypt
or hashed with SHA256
before stored (default: plain)For refresh tokens, again, the Doorkeeper::OAuth::Helpers::UniqueToken
generator is used.
The ability to set the access token generator using Doorkeeper.configuration.access_token_generator
, makes it possible to plug in different token generators such as JWT.
Token recipients (e.g. an API) should verify the received tokens using the Token Introspection endpoint (documentation) as defined in RFC7662. Tokens can be revoked using the Token Revocation endpoint (documentation) as defined in RFC7009
My recommendation is to avoid writing your own security related code and use existing open-source solutions such as Doorkeeper, which are peer-reviewed and already trusted by many companies / projects (aka. "Do not roll your own crypto"). It's very easy to make security-related mistakes and jeopardize the security and/or privacy of your customers.