ruby-on-railsrubyoauth-2.0doorkeeper

What technology or algorithm Doorkeeper use to generate it's refresh tokens and access tokens and why is it secured


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.


Solution

  • 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:

    1. After successfully authenticating but before responding a new Doorkeeper::AccessToken will be created
    2. The AccessTokenMixin#generate_token method is called (before callback)
    3. The #token_generator method is called
    4. The default UniqueToken token generator is returned
    5. Back in #generate_token the token_generator#generate method is called
    6. The token is generated using SecureRandom
    7. Back in #generate_token the secret can be encrypted using bcrypt or hashed with SHA256 before stored (default: plain)
    8. The token is saved in the database and returned to the caller

    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.