Pergunta

We have encountered an issue during development of an application for the new Google Apps Marketplace using Oauth2.0 for SSO.

As a part of our application we are using the Google Calendar V3 API, on offline mode - meaning we are required to keep a 'refresh_token' for our clients.

In order to get the 'refresh_token' during the first OAuth2.0 authentication we need to configure the google_oauth2.0 provider (using omniauth-google-oauth2 gem) such as:

Rails.application.config.middleware.use OmniAuth::Builder do
    provider :google_oauth2, CONFIG[:app_id], CONFIG[:app_secret], {
    access_type: 'offline',
    prompt: 'consent' }
 end

Without specifying the access_type: 'offline, and prompt:'consent' we do not receive the refresh_token, and can not use the calendar API properly.

However, specifying the prompt: 'consent' attribute, leads to an authorization popup, which negates the whole SSO idea - where only the domain admin gets prompted during installation.

Is it possible to get the refresh_token without prompting the domain users? How does new Google Apps Marketplace support offline access without prompting of end-users?

Foi útil?

Solução

It looks like a service account for offline access was what I'm looking for.

Inspired by this thread: Trouble with Google Apps API and Service Accounts in Ruby

I found out that I can create a service account on the apps marketplace configuration. Project -> APIs & Auth -> Credentials -> Create New Client Id -> Choose Service account. And in my code use Signet to provide domain level authorization for the end-users:

key = Google::APIClient::PKCS12.load_key('privatekey.p12', 'notasecret')
client = Google::APIClient.new

client.authorization = Signet::OAuth2::Client.new(
        :token_credential_uri => 'https://accounts.google.com/o/oauth2/token',
        :audience => 'https://accounts.google.com/o/oauth2/token',
        :scope => 'https://www.googleapis.com/auth/calendar',
        :issuer => '<email-address-of-service-account>@developer.gserviceaccount.com',
        :signing_key => key,
        :person => email)
client.authorization.fetch_access_token!

Not only does this allowed me to authenticate without prompting the end-user at any phase during the process - but I don't require the refresh_token anymore, and I can execute the API calls with domain level authorizations. The person option allows me to specify which end-user I'm using the API call for.

Outras dicas

As answered in this question( Google Apps Marketplace SDK + Domain-wide OAuth 2 SSO ), the domain users will always be prompted with the authorization page when doing OAuth2.0 if you are asking for offline access from your application.

However, I don't think this denies the SSO concept, since the offline permission will only be given the first time an user accesses your app. After giving permissions your app won't ask for them again( if the prompt:'consent' parameter you have in your library translates into approval_prompt:'auto' like it is in the OAuth2.0 login documentation ).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top