Reputation: 73
I have a service account and I am using the OAuth2 gem together with the Google API Ruby Client:
require 'oauth2'
require 'google/api_client'
My objective is to fetch an access token which allows access to a specific user’s account and no other. I think this is often achieved using the sub
parameter when using HTTP, but how do I do this using the Ruby client libraries above?
I can get an access token successfully and use it to access the drive v2 file list API. I always see a single "How to get started with Drive" document in the response and no other.
I suspect my attempt to impersonate a user has not succeeded. Basically I’m passing in an email address as a sub
option to the function below:
client = Google::APIClient.new(...)
access_token = OAuth2::AccessToken.new(oauth2_client, client.authorization.access_token, {‘sub’ => ‘[email protected]’} )
Presumably that isn’t the way to do this.
How to I retrieve an access token which is scoped to permit access impersonating a single user and no other?
Following Steve's comment I have dropped the intridea Gem and am now using Signet. I get a little further but I am stuck getting an access_denied error when I specify a :person. Without that I can authenticate but obviously I get access as the issuer.
require 'google/api_client'
...
client = Google::APIClient.new(:application_name => application_name, :application_version => application_version)
...
opts = {
:token_credential_uri => 'https://accounts.google.com/o/oauth2/token',
:audience => 'https://accounts.google.com/o/oauth2/token',
:scope => scope,
:issuer => service_account_email_address,
:signing_key => key,
:person => '[email protected]'
})
client.authorization = Signet::OAuth2::Client.new(opts)
access_token = client.authorization.fetch_access_token!
...
>> client.authorization.fetch_access_token!
Signet::AuthorizationError: Authorization failed. Server message:
{
"error" : "access_denied",
"error_description" : "Requested client not authorized."
}
I have a console project which I do a 'test install flow' on but the client does not seem to be trusted. Where do I look?
Thanks.
Upvotes: 2
Views: 1933
Reputation: 73
Here's the summary.
Do not use the OAuth2 gem from intridea if you are only trying to authenticate with Google. Rely on the signet Gem.
If you use a service account, you can specify a :person element and it will work so you impersonate that user and work on their behalf.
When you test your integration you must do so against the domain in which your project is hosted. You cannot test in a third-party domain until you've published your app!
Upvotes: 1
Reputation: 11672
Not sure how to do it with intridea's oauth2 gem, but the signet, the default for the ruby client library, handles this case directly.
There's a snip-it for how to do this in the readme. The only addition is, as you point out, adding the subject to get a token for the specific user. That can be specified either when instantiating the OAuth2 client or as an option to fetch_access_token!
Upvotes: 1