Re: How to authenticate using OAuth2 without user entering credential values

20,378 views
Skip to first unread message

Joseph DiLallo (DFA API Team)

unread,
Jan 3, 2013, 9:51:11 AM1/3/13
to google-doubleclick-...@googlegroups.com, justche...@gmail.com
Greetings!

We recommend you use the Installed Application Flow for OAuth 2. You do need to use a browser to generate credentials, but you only have to do it exactly once if you securely store your refresh token persistently. You don't need the reporting application itself to spawn the browser window - you can authenticate on another machine and then pass the refresh token to a location your background job can access.

Regards,
- Joseph DiLallo, the DFA API Team

On Wednesday, January 2, 2013 4:34:15 PM UTC-5, justche...@gmail.com wrote:
So, we have an existing job setup to get Double Click reports. To authenticate the credential we make a call to the API like below (in .Net C#)

using com.doubleclick.dfa;

OrganizationFactory.getOrganization(uid, pwd, Url);

Now we are planning to use the new .Net API for DFA and OAuth2. In the Sample Applications available on Google, Tasks.SimpleOAuth2, it spawns a browser window to get the Authorization Code.

My question is how can I get the Authorization code without spawning a browser window, as this is going to be a background job? And the users accounts are created by us and we have the credentials.

Any suggestions? Thanks.

Joseph DiLallo (DFA API Team)

unread,
Jan 4, 2013, 4:25:08 PM1/4/13
to google-doubleclick-...@googlegroups.com, justche...@gmail.com
Hello again,

Ah, service accounts. These cause a lot of confusion. Are you using the "prn" field to request an additional claim? (See the "Additional Claims" section in the documentation).

The reason service accounts are so confusing is that they are considered their own user, their own Google Account. For example, lets say your DFA user profile is connected to the Google Account exa...@gmail.com. You can access the DFA website using exa...@gmail.com. You go to the Google APIs Console and generate a service account. If you use this service account, you cannot access the DFA user profile attached to exa...@gmail.com. This is because the service account isn't tied to your DFA user profile - exa...@gmail.com is. You need to claim (see: impersonate) exa...@gmail.com in order for this to work. You do so using that "prn" field.

We have a guide about how to set up impersonation for DoubleClick for Publishers. If you just replace DFP with DFA (including which OAuth scope you need access to), it's 100% applicable to DFA. You can find it here: https://developers.google.com/doubleclick-publishers/docs/service_accounts

Service accounts are often more trouble than their worth, especially since you need a Google Apps domain to access DFA with it. Unless you really want impersonating capabilities, it's far easier to use the installed application flow. Just swap out your service account key file for a persistently stored refresh token and its basically the same thing.

- Joseph DiLallo, the DFA API Team

On Friday, January 4, 2013 3:20:44 PM UTC-5, justche...@gmail.com wrote:
Thanks for your response. I read a bit more on the DFA Reporting API and now am a bit more clear about my issue.

The authentication I am looking for is "Service Accounts" as described here: https://developers.google.com/accounts/docs/OAuth2

I was able to write a code snippet that would get me the access token for my "google account" .

What I am trying to do:
Under our account we have got various "DFA accounts". I am trying to connect to my account using the access token that I generate at run-time. The JSON I receive through my method looks like below:
{
  "access_token" : "ya29.......FJ1A",
  "token_type" : "Bearer",
  "expires_in" : 3600
}

Where I am:
I have got VS 2012 sample downloaded that has examples on how to make calls to DFA service (using the user prompt that I am trying to avoid here). I have adopted the code and intialized the DfaUser object as shown here: https://code.google.com/p/google-api-dfa-dotnet/wiki/HowToUseADfaUser (DfaUser(Dictionary<string, string> headers) constructor). I use the access token I got for the "authToken" header value.

Alternate tried so far:
I also tried the approach described here Configure your DfaUser to use OAuth: https://code.google.com/p/google-api-dfa-dotnet/wiki/UsingOAuth
I do not have a refresh token value so I did not set anything there.

Error:
When executing code with above setup, I get error at

UserRecordSet users = service.getUsersByCriteria(searchCriteria); //service is UserRemoteService

Error message: org.apache.ws.security.WSSecurityException: General security error (WSSecurityEngine: Callback supplied no password for: <username>)

Error for Alternate:
The error I get for trying the alternate method is: 101026 - Invalid OAuth2 token sent with this request.

Would you be able to point out what I am doing wrong and what should I modify? Your response is greatly appreciated.

Thanks.

Joseph DiLallo (DFA API Team)

unread,
Apr 24, 2013, 11:23:26 AM4/24/13
to google-doubleclick-...@googlegroups.com, justche...@gmail.com, sankar....@gmail.com
Hi Sankar,

You don't have to generate the refresh token from the server where your application resides. Refresh tokens are really just strings; you can generate one anywhere and just pass it into your application.

If the examples in our sample code aren't helping you and you're having difficulty generating the refresh token from code, you could use the Google OAuth 2.0 Playground to generate your refresh token. You can do so like this:
  1. Click the gear icon in the upper-right. Check the "Use your own OAuth credentials" box and input your Client ID and Client Secret
  2. On the left side of the screen, input the OAuth scopes you need access to in the text box before clicking "Authorize APIs". The DFA scopes don't show up here, you'll have to input them yourself.
  3. Click "Authorize APIs"
  4. Click "Grant access" at the OAuth 2.0 permissions screen
  5. Click the "Exchange authorization code for tokens" button
  6. Your refresh token is displayed. You can use this refresh token and the Client ID / Secret you entered in Step 1 to authorize your application
Regards,
- Joseph DiLallo, the DFA API Team

On Wednesday, April 24, 2013 10:04:13 AM UTC-4, sankar....@gmail.com wrote:
Hi Joseph DiLallo,
 
We are developing a windows service to retrieve the DFA data using "Google.Apis.Dfareporting.v1.1.cs" API in C#.
We can't open the browser through windows service even once. Is there a solution for our problem. We want our system
fully automated that we want to avoid opening the browser to generate credential even once.
 
"Installed Application Flow" for OAuth2 is cumbersome to follow, Can you share the simple steps or the sample c# code
to auto-authenticate.

Joseph DiLallo (DFA API Team)

unread,
Apr 25, 2013, 11:32:44 AM4/25/13
to google-doubleclick-...@googlegroups.com, justche...@gmail.com, sankar....@gmail.com
Hi Sankar,

With the OAuth2 2.0 Playground, you need to put the scope in yourself in the input box. DFA is not one of the ones listed by default. The DFA Reporting API currently uses https://www.googleapis.com/auth/dfareporting but you'll also want access to https://www.googleapis.com/auth/devstorage.read_only in order to download report files.

With your code, I think the problem is that you're not setting the RefreshToken on AuthorizationState. I recommend that you look at the implementation of the AuthorizationMgr class. All it's doing in the getCachedRefreshToken method is this (minus the storage part):

return new AuthorizationState(scopes) { RefreshToken = refreshToken };

You should be able to do the same thing with your scopes and refresh token to get a usable AuthorizationState.

Regards,
- Joseph DiLallo, the DFA API Team

On Thursday, April 25, 2013 8:56:44 AM UTC-4, sankar....@gmail.com wrote:
Hi Joseph,
 
I don't find dfa api listed in Google OAuth 2.0 Playground. Can you please clarify which option to choose.

Joseph DiLallo (DFA API Team)

unread,
Apr 26, 2013, 1:50:47 PM4/26/13
to google-doubleclick-...@googlegroups.com, justche...@gmail.com, sankar....@gmail.com
Hi Sankar,

You're passing in an empty array of scopes. You need to be passing in the scopes you need access to. Something like this should work:

private static readonly string DfaReportingScope = DfareportingService.Scopes.Dfareporting.GetStringValue();
       private const string DevStorageScopeReadOnly = "https://www.googleapis.com/auth/devstorage.read_only";        private const string[] scopes = new string[] { DfaReportingScope, DevStorageScopeReadOnly };

then pass the scopes parameter into the AuthorizationState constructor.

Cheers,
- Joseph DiLallo, the DFA API Team

On Thursday, April 25, 2013 11:45:05 AM UTC-4, sankar....@gmail.com wrote:
Hi Joseph,
 
I have set the refreshtoken on authorization state in the below given code step -
 
AuthorizationMgr.SetCachedRefreshToken(storage, key, new AuthorizationState(new string[] { })
                {
                    AccessToken = "*******",
                    RefreshToken = "******"
                }
);
 
Can you please share any sample code.

Joseph DiLallo (DFA API Team)

unread,
May 2, 2013, 4:42:43 PM5/2/13
to google-doubleclick-...@googlegroups.com, justche...@gmail.com, sankar....@gmail.com
Hi Sankar,

Hmm.. I'm really not sure why that wouldn't work. Doing exactly that works for me when I try. It seems like the answers on Stack Overflow point to the same solution: http://stackoverflow.com/questions/7454930/google-api-how-can-i-use-refreshtokens-to-avoid-requesting-access-every-time-m

All they're doing here is basically

IAuthorizationState state = new AuthorizationState(new[] { "https://www.googleapis.com/auth/dfareporting", "https://www.googleapis.com/auth/devstorage.read_only" });
string refreshToken = "REFRESH_TOKEN_HERE";
state.RefreshToken = refreshToken; 
return state;

If that doesn't work, I recommend asking on StackOverflow. This is really the limit of my familiarity with the library, unfortunately.

Regards,
- Joseph DiLallo, the DFA API Team

On Monday, April 29, 2013 3:09:17 AM UTC-4, sankar....@gmail.com wrote:
Hi Joseph,

Tried your below suggestion, I got the error - "Error occurred while sending a direct message or getting the response". I was caught in the catch block -
catch (DotNetOpenAuth.Messaging.ProtocolException ex) :)

If you could share me a plug-in-play working "private static IAuthorizationState GetAuthorization(NativeApplicationClient client)" method sample, for authenticating without the user intervention (without the browser open for "allow access" button click).

Regards,
Joseph

Wei Sun

unread,
Jan 22, 2014, 2:23:26 PM1/22/14
to google-doubleclick-...@googlegroups.com, justche...@gmail.com
Hi Joseph, 

I was trying to follow your instructions below to create a refresh token. In step 2, I selected Dfa Reporting API. I got the following error at step 3 after clicking "Authorize APIs". And when I go back to the gear icon, changes I made in step 1 got reversed. The "Use your own OAuth credentials" box is unchecked.

Error: redirect_uri_mismatch

Request Details

Wei 

Jonathon Imperiosi (DFA API Team)

unread,
Jan 22, 2014, 2:59:27 PM1/22/14
to google-doubleclick-...@googlegroups.com
Hello Wei,

You'll need to add the OAuth Playground as a valid redirect URI for your project for this to work. There are instructions for doing this directly above where you enter you client ID and secret in step 1. Basically you will need to create a client ID for web application within your project, and add https://developers.google.com/oauthplayground as a valid redirect URI.

Regards,
- Jonathon Imperiosi, DFA API Team
Message has been deleted
Message has been deleted

Wei Sun

unread,
Jan 23, 2014, 10:31:41 AM1/23/14
to google-doubleclick-...@googlegroups.com
Hi Jonathon, 

Thanks for your reply. I get the refresh token now by creating a new web application. But can I get a refresh token for installed application? My application is going to run on a server. 

Wei 

Jonathon Imperiosi (DFA API Team)

unread,
Jan 23, 2014, 11:00:12 AM1/23/14
to google-doubleclick-...@googlegroups.com
Hi Wei,

Unfortunately the OAuth Playground can't generate a refresh token for an installed application. Depending on what language you are writing your application in, we may have sample code to help with generating a refresh token (see above for C#). Remember that generating a refresh token is a one-time process, so you can write some code to do this generation locally, and then deploy the token with your finished application to the server.

Regards,
- Jonathon Imperiosi, DFA API Team

Message has been deleted
Message has been deleted
Message has been deleted

Wei Sun

unread,
Jan 24, 2014, 10:43:06 AM1/24/14
to google-doubleclick-...@googlegroups.com
Hi Jonathon, 

I have generated a refresh token (and an access token that will expire in an hour). How do I authenticate using the refresh token? It seems some of the sample code mentioned in the above posts have changed. For example, Class NativeApplicationClient is part of Google.Apis.Authentication. Google.Apis.Authentication is obsolete now and we should use Google.Apis.Auth instead. But Google.Apis.Auth doesn't have NativeApplicationClient. 

Do you have any code snippet in C# that you can share? Thanks a lot!

Wei

Jonathon Imperiosi (DFA API Team)

unread,
Jan 24, 2014, 12:42:42 PM1/24/14
to google-doubleclick-...@googlegroups.com
Hi Wei,

I'm not sure which API you're using, but you can find sample code for the DFA API here and the DFA Reporting API here. Most samples use the installed application workflow and work with pre-generated refresh tokens.

Regards,
- Jonathon Imperiosi, DFA API Team

Wei Sun

unread,
Jan 24, 2014, 1:33:20 PM1/24/14
to google-doubleclick-...@googlegroups.com
Hi Jonathon, 

I am using DFA Reporting API. I have looked at the sample code you posted. It uses installed application but not pre-generated refresh token. Line 102 will open a browser window and ask user to approve which is what I want to avoid as my app will run on a server. Please let me know if I am wrong.

Wei

Jonathon Imperiosi (DFA API Team)

unread,
Jan 24, 2014, 2:02:44 PM1/24/14
to google-doubleclick-...@googlegroups.com
Hi Wei,

That example does actually use refresh tokens, although it may not be obvious. The last parameter to the AuthorizeAsync() method is a FileDataStore object, which is used to store the retrieved access and refresh tokens. Once this file is populated (after you go through the web browser process once), the code will use the refresh token stored in this file for all subsequent authorization requests.

If for some reason the FileDataStore doesn't work for you, you can plug in a different object that implements the IDataStore interface. You can find a few options by searching on stack overflow (see here as an example).

Regards,
- Jonathon Imperiosi, DFA API Team

Reply all
Reply to author
Forward
Message has been deleted
0 new messages