Using Resource Owner Password Credentials flow

Michael Monerau edited this page Oct 25, 2018 · 18 revisions

NOTE: See this issue in case this implementation is buggy: https://github.com/doorkeeper-gem/doorkeeper/issues/475#issuecomment-107501342.

In this flow, a token is requested in exchange for the resource owner credentials (username and password):

Configuration

To use this flow you first have to tell doorkeeper how to authenticate the resource owner with username/password:

Doorkeeper.configure do
  resource_owner_from_credentials do |routes|
    User.authenticate!(params[:username], params[:password])
  end
end

For Doorkeeper 2.1+, you'll need to add password as an acceptable grant type. In your initializer, make sure password is part of your grant_flows so you have at least (you can have others):

grant_flows %w[password]

Newer versions of devise don't provide the authenticate! method anymore, and you can use:

Doorkeeper.configure do
  resource_owner_from_credentials do |routes|
    user = User.find_for_database_authentication(:email => params[:username])
    if user&.valid_for_authentication? { user.valid_password?(params[:password]) } && user&.active_for_authentication?
      user
    end
  end
end

Alternatively, you can also run the authentication through warden. This requires some trickery though:

Doorkeeper.configure do
  resource_owner_from_credentials do |routes|
    request.params[:user] = {:email => request.params[:username], :password => request.params[:password]}
    request.env["warden"].logout(:user)
    request.env["devise.allow_params_authentication"] = true
    request.env["warden"].authenticate!(:scope => :user, :store => false)
  end
end

Testing

For testing you can use the oauth2 ruby gem:

client = OAuth2::Client.new('the_client_id', 'the_client_secret', :site => "http://example.com")
access_token = client.password.get_token('user@example.com', 'sekret')
puts access_token.token

NOTE: this syntax might be old, password grant flow doesn't need client credentials. See https://github.com/doorkeeper-gem/doorkeeper/issues/561.

That will make a POST request to the OAuth providers /oauth/token endpoint, with the params:

{
  "grant_type"    : "password",
  "username"      : "user@example.com",
  "password"      : "sekret"
}

Then, you'll receive the access token back in the response:

{
  "access_token": "1f0af717251950dbd4d73154fdf0a474a5c5119adad999683f5b450c460726aa",
  "token_type": "bearer",
  "expires_in": 7200
}

Links:

You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.