?
Solved

Google Data Authentication in C# with 2-Step Verification

Posted on 2014-09-19
6
Medium Priority
?
1,789 Views
Last Modified: 2015-03-02
using System;
//using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;

using Google.GData.Client;
using Google.GData.Extensions;
using Google.GData.Calendar;
using System.Diagnostics;

namespace RepBusGoogleCalandar
{
    public class CalandarMain
    {

        public bool m_isInitialized;
        private CalendarService m_calServiceSDER;
        public gcEvent m_gcEvent;
        private EventQuery m_query;
        private EventFeed m_feed;
        public const char fs = (char)29;//13; //field separator

        public CalandarMain()
        {
            RefreshFeed();
        }

        ~CalandarMain()
        {
            
        }

        //OAuth 2.0

        private void RefreshFeed()
        {
            bool bolGood;

            m_calServiceSDER = new CalendarService("SDERcalApp");
            m_calServiceSDER.setUserCredentials("MyUN", "MyPW");   // <----- UN and PW hard coded here

            //InvalidCredentialsException
            m_query = new EventQuery();
            m_query.Uri = new Uri(calendarURI);
            m_query.NumberToRetrieve = int.MaxValue;
            bolGood = false;
            try
            {
                m_feed = m_calServiceSDER.Query(m_query) as EventFeed;
                bolGood = true;
            }
            catch (Exception e)
            {
                string cs_err;
                cs_err = e.Message;
                Console.WriteLine(cs_err);
                Console.WriteLine(e.Source);
                //MessageBox.Show(cs_err, e.Source);
            }
            m_gcEvent = new gcEvent();
            if(bolGood)
            {
                Console.WriteLine("****** RefreshFeed: calFeed.Entries.Count: " + m_feed.Entries.Count);
            }
            m_isInitialized = bolGood;
        }
}

Open in new window


This code listed here worked just fine until I set up Google 2-Step Verification.
https://www.google.com/landing/2step/

Question: What extra code is needed to deal with the Google 2-Step Verification process?
NOTE: Look were I have the //InvalidCredentialsException notation.

Thanks!
 - Dave
0
Comment
Question by:AviationAce
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
6 Comments
 
LVL 82

Expert Comment

by:David Johnson, CD, MVP
ID: 40334019
use an application password https://www.google.com/settings/security
0
 

Author Comment

by:AviationAce
ID: 40334351
I understand that in concept, but need help in hammering out the details.  If you were going to modify the class I posted, where exactly would you start?

Please note: I have already created a new "Client ID for native application" at the Google Developers Console.  See the attachment.
Screenshot-2014-09-20-08.07.59.png
0
 

Author Comment

by:AviationAce
ID: 40339255
It appears to me that modifying the old class is not feasible.  So, I am writing a new one using the new V3 interface.

I'm getting a type conversion error and I don't understand why.  Please look at the comment that starts with Error 1 and advise.

using System;
using System.IO;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using System.Diagnostics;

//For use in class CalandarMain
//using Google.GData.Client;
//using Google.GData.Extensions;
//using Google.GData.Calendar;


//For use in class CalandarMainV3  :  An entirly new class needed to 
using System.Threading;
using System.Threading.Tasks;
using Google;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Calendar.v3;
using Google.Apis.Calendar.v3.Data;
using Google.Apis.Services;
using Google.Apis.Util.Store;

    public class CalandarMainV3
    {
        const String ClientSecretsFile = "C:\\Users\\User1\\Documents\\Visual Studio 2010\\Projects\\Programming\\Projects\\Google Ops\\client_secrets.json";

        const String CalAppName = "MyCalAppV3";

        bool m_Init;

        public CalandarMainV3()
        {
            m_Init = AuthGoogleDataInterface();
        }

        private bool AuthGoogleDataInterface()
        {
            bool b_success;
            try
            {
                UserCredential credential;

                using (var stream = new FileStream(ClientSecretsFile, FileMode.Open, FileAccess.Read))
            {
                //Error	1	Cannot implicitly convert type 'System.Threading.Tasks.Task<Google.Apis.Auth.OAuth2.UserCredential>' to 'Google.Apis.Auth.OAuth2.UserCredential'	C:\Users\user1\Documents\Visual Studio 2010\Projects\Programming\Projects\Google Ops\RepBusGoogleCalandar\RepBusGoogleCalandar\ClalandarMain.cs	273	30	RepBusGoogleCalandar
                credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
                    GoogleClientSecrets.Load(stream).Secrets,
                    new[] { Google.Apis.Calendar.v3.CalendarService.Scope.Calendar },
                    "user",
                    CancellationToken.None,
                    new FileDataStore("Calendar.MyCal")
                    );
            }
                Console.WriteLine("AuthGoogleDataInterface: Success");
                b_success = true;
            }
            catch (Exception e)
            {
                string cs_err;
                cs_err = e.Message;
                Console.WriteLine(cs_err);
                Console.WriteLine(e.Source);
                Console.WriteLine("AuthGoogleDataInterface: Fail");
                b_success = false;
                throw;
            }

            return b_success;
        }
    }
}

Open in new window

0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 

Author Comment

by:AviationAce
ID: 40347101
The code below complies correctly and runs, but I am now having a problem with the CLIENT SECRETS file.

using System;
using System.IO;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using System.Diagnostics;

//For use in class CalandarMainV3  :  An entirely new class needed to 
using System.Threading;
using System.Threading.Tasks;
using Google;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Calendar.v3;
using Google.Apis.Calendar.v3.Data;
using Google.Apis.Services;
using Google.Apis.Util.Store;

namespace RepBusGoogleCalendarV3
{
    public class CalandarMainV3
    {
        const String ClientSecretsFile = "C:\\Users\\user1\\Documents\\Visual Studio 2010\\Projects\\Programming\\Projects\\Google Ops\\client_secrets.json";

        bool m_Init;

        public CalandarMainV3()
        {
            Console.WriteLine("Calling: AuthGoogleDataInterface()");
            m_Init = AuthGoogleDataInterface();
        }

        private bool AuthGoogleDataInterface()
        {
            bool b_success;
            try
            {
                Console.WriteLine("New User Credential");
                // New User Credential
                UserCredential credential;
                using (var stream = new FileStream(ClientSecretsFile, FileMode.Open, FileAccess.Read))
                {
                    credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
                        GoogleClientSecrets.Load(stream).Secrets,
                        new[] { CalendarService.Scope.Calendar },
                        "user", CancellationToken.None,
                        null).Result;
                        //new FileDataStore("My.cal")).Result;
                }

                Console.WriteLine("New Service");
                // Create the service.
                var service = new CalendarService(new BaseClientService.Initializer
                {
                    HttpClientInitializer = credential,
                    ApplicationName = "My Calendar API",
                });
                
                Console.WriteLine("AuthGoogleDataInterface: Success");
                b_success = true;
            }
            catch (Exception e)
            {
                string cs_err;
                cs_err = e.Message;
                Console.WriteLine(cs_err);
                Console.WriteLine(e.Source);
                Console.WriteLine("AuthGoogleDataInterface: Fail");
                b_success = false;
                throw;
            }
            return b_success;
        }
    }
}

Open in new window


Contents of the client_secrets.json file.

{"installed":{"auth_uri":"https://accounts.google.com/o/oauth2/auth","client_secret":"xxxxxxxxxxxxxxxxxxxxxxxx","token_uri":"https://accounts.google.com/o/oauth2/token","client_email":"","redirect_uris":["urn:ietf:wg:oauth:2.0:xxx","xxx"],"client_x509_cert_url":"","client_id":"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs"}}

Open in new window


When I run the program, it loads a web page with the following contents:

401. That’s an error.

Error: invalid_client

no application name

Request Details
scope=https://www.googleapis.com/auth/calendar
response_type=code
redirect_uri=http://localhost:00000/authorize/
access_type=offline
client_id=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com

That’s all we know.

What am I doing wrong?
0
 

Accepted Solution

by:
AviationAce earned 0 total points
ID: 40347667
stackoverflow.com/questions/18677244/error-invalid-client-no-application-name

At the link above I discovered that the error was being caused because I had not set up "Project Name" in my Google APIs Dashboard.

After setting it up the code ran with out error.  The first time I ran it a web page was displayed asking me to ok this device to use the service.
0
 

Author Closing Comment

by:AviationAce
ID: 40361055
That fact that a project name hadn't been set up yet was key.  That should be documented better.
0

Featured Post

Get MongoDB database support online, now!

At Percona’s web store you can order your MongoDB database support needs in minutes. No hassles, no fuss, just pick and click. Pay online with a credit card. Handle your MongoDB database support now!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Working with spreadsheets can be a daunting task, especially when having to deal with large amounts of data. All you see are rows and rows of numbers and soon your eyes begin to glaze over. Take advantage of the tools in Google Sheets to create prof…
Google is more than just a search engine. Over the years the company has developed a wide range of online services that are readily available to all users. This article highlights how one can use Google services for simple project management.
This Micro Tutorial demonstrates the importance of annotations in Google Analytics and how they should be used to document changes made to a site, Google updates (Ex: Panda & Penguin), marketing campaigns, and any other events that might have contri…
In this Experts Exchange video Micro Tutorial, I'm going to show how small business owners who use Google Apps can save money by setting up what is called a catch-all email address in their Gmail accounts. By using the catch-all feature, small busin…
Suggested Courses
Course of the Month11 days, 14 hours left to enroll

752 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question