Search code examples
asp.net-mvcasp.net-web-apigoogle-analyticsgoogle-analytics-apiaccess-denied

"Access_Denied" for Google Analytics


I am implementing oAuth flow in my asp.net webapi 2. I have to get permission from user to access their google analytics data. and for that I have added below scopes while sending authentication request to google oAuth2.0 flow. In response of this I am always getting "Access_Denied" error even user clicks "Allow Access" button on consent screen.

The same code is working fine and getting External Access Token if I am not adding Google Analytic in scope.

Also I have enabled Google analytic API in google developer console.

Google Analytic Scopes :

googleAuthOptions.Scope.Add(AnalyticsService.Scope.Analytics);
googleAuthOptions.Scope.Add(AnalyticsService.Scope.AnalyticsReadonly);
googleAuthOptions.Scope.Add(AnalyticsService.Scope.AnalyticsManageUsers);

Code written in WebApi's startup.cs file:

//Configure Google External Login
GoogleOAuth2AuthenticationOptions googleAuthOptions = new GoogleOAuth2AuthenticationOptions()
{
    ClientId = ConfigurationManager.AppSettings["GoogleClientID"],
    ClientSecret = ConfigurationManager.AppSettings["GoogleClientSecret"],
    Provider = new GoogleAuthProvider()
};

//1st trial=> 
//googleAuthOptions.Scope.Add("https://www.googleapis.com/auth/analytics");

//2nd trial
//googleAuthOptions.Scope.Add(AnalyticsService.Scope.Analytics);
//googleAuthOptions.Scope.Add(AnalyticsService.Scope.AnalyticsReadonly);            
//googleAuthOptions.Scope.Add(AnalyticsService.Scope.AnalyticsManageUsers);

app.UseGoogleAuthentication(googleAuthOptions);

Method in WebAPI's Controller [ExternalLogin]:

[OverrideAuthentication]    
[HostAuthentication(DefaultAuthenticationTypes.ExternalCookie)]
    [AllowAnonymous]
    [Route("ExternalLogin", Name = "ExternalLogin")]
    public async Task<IHttpActionResult> GetExternalLogin(string provider, string error = null)
    {
        string redirectUri = string.Empty;

        if (error != null)
        {
            return BadRequest(Uri.EscapeDataString(error));
        }

        if (!User.Identity.IsAuthenticated)
        {
            return new ChallengeResult(provider, this);
        }

        var redirectUriValidationResult = ValidateClientAndRedirectUri(this.Request, ref redirectUri);

        if (!string.IsNullOrWhiteSpace(redirectUriValidationResult))
        {
            return BadRequest(redirectUriValidationResult);
        }

        ExternalLoginData externalLogin = ExternalLoginData.FromIdentity(User.Identity as ClaimsIdentity);

        if (externalLogin == null)
        {
            return InternalServerError();
        }

        if (externalLogin.LoginProvider != provider)
        {
            Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie);
            return new ChallengeResult(provider, this);
        }

        //IdentityUser user = await _repo.FindAsync(new UserLoginInfo(externalLogin.LoginProvider, externalLogin.ProviderKey));

        int profileID = Convert.ToInt32(HttpContext.Current.Request.QueryString["profile_id"]);

        var user = new UserRepository().SearchProfileByID(profileID);

        bool hasRegistered = user != null;

        redirectUri = string.Format("{0}#external_access_token={1}&provider={2}&haslocalaccount={3}&external_user_name={4}",
                                        redirectUri,
                                        externalLogin.ExternalAccessToken,
                                        externalLogin.LoginProvider,
                                        hasRegistered.ToString(),
                                        externalLogin.UserName);

        return Redirect(redirectUri);

    }

I have followed this link to implement the oAuth functionality.

Please help me to get solution of this issue.

Thanks


Solution

  • Finally I got solution of my question, We need to add the "email" scope too. I added below 2 scopes to make it working:

    googleAuthOptions.Scope.Add("email");  
    googleAuthOptions.Scope.Add("https://www.googleapis.com/auth/analytics.readonly");
    

    This is now returning me the external token with the access of google analytic api

    Thanks

    Vijay