5

Я пытаюсь использовать AccessToken, предоставленный Owin, в запросах Google.Apis, но я получаю исключение System.InvalidOperationException (Дополнительная информация: токен доступа истек, но мы не можем его обновить).Как я могу использовать ASP.NET MVC Owin AccessToken в вызове Google.Apis?

Моя конфигурация аутентификации Google в порядке, и я могу успешно войти в мое приложение вместе с ней. Я сохраняю context.AccessToken в качестве претензии в обратном вызове аутентификации (OnAuthenticated "событие" GoogleOAuth2AuthenticationProvider).

Моя конфигурация Startup.Auth.cs (app.UseGoogleAuthentication (ConfigureGooglePlus()))

private GoogleOAuth2AuthenticationOptions ConfigureGooglePlus() 
{ 
var goolePlusOptions = new GoogleOAuth2AuthenticationOptions() 
{ 
    ClientId = "Xxxxxxx.apps.googleusercontent.com", 
    ClientSecret = "YYYYYYzzzzzz", 
    Provider = new GoogleOAuth2AuthenticationProvider() 
    { 
     OnAuthenticated = context => 
     { 
      context.Identity.AddClaim(new System.Security.Claims.Claim("Google_AccessToken", context.AccessToken)); 
      return Task.FromResult(0); 
     } 
    }, 
    SignInAsAuthenticationType = DefaultAuthenticationTypes.ExternalCookie 
}; 

goolePlusOptions.Scope.Add("https://www.googleapis.com/auth/plus.login"); 
goolePlusOptions.Scope.Add("https://www.googleapis.com/auth/userinfo.email"); 

return goolePlusOptions; 

}

Код, в котором исключение бросили (Execute() метод)

var externalIdentity = await AuthenticationManager.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie); 

var accessTokenClaim = externalIdentity.FindAll(loginProvider + "_AccessToken").First(); 

var secrets = new ClientSecrets() 
{ 
    ClientId = "Xxxxxxx.apps.googleusercontent.com", 
    ClientSecret = "YYYYYYzzzzzz" 
}; 

IAuthorizationCodeFlow flow = 
    new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer 
    { 
     ClientSecrets = secrets, 
     Scopes = new[] { PlusService.Scope.PlusLogin, PlusService.Scope.UserinfoEmail } 
    }); 

UserCredential credential = new UserCredential(flow, "me", new TokenResponse() { AccessToken = accessTokenClaim.Value }); 

var ps = new PlusService(
    new BaseClientService.Initializer() 
    { 
     ApplicationName = "My App Name", 
     HttpClientInitializer = credential 
    }); 

var k = ps.People.List("me", PeopleResource.ListRequest.CollectionEnum.Visible).Execute(); 

есть еще один способ, чтобы получить оригинальный маркер доступа или Refre sh без прохода через весь процесс аутентификации (пользователь уже прошел аутентификацию)?

Мне нужно запросить данные профиля GooglePlus, такие как имя, фамилия, пол, профиль и профиль.

+0

** UPDATE ** я получил его работу с помощью значения, полученные с помощью «OAuth 2.0 Playground», и проблема, связанная с ее работой, заключается в том, что RefreshToken является нулевым в контексте, и я не знаю, как получить новый. –

+0

Я не пробовал то, что вы делаете раньше. Но когда вы запрашиваете доступ из google, вы также должны добавить AccessType в автономном режиме, это скажет серверу аутентификации, чтобы вернуть вам сообщение refreshtoken. Клиентская библиотека должна обрабатывать это для вас. – DaImTo

+0

Можете ли вы приложить исключение? Я не уверен, что вы можете получить RefreshToken из externalIdentity, но я бы рекомендовал вам начать его исследовать, поскольку в клиентской библиотеке должен быть токен обновления, чтобы ваш токен доступа был свежим (срок действия истекает через 60 минут) – peleyal

ответ

5

Linda помог мне с URL-адресом, указывающим на новый образец asp.net mvc (https://codereview.appspot.com/194980043/).

Мне просто нужно было добавить AccessType = "offline" в GoogleOAuth2AuthenticationOptions и сохранить дополнительную информацию, чтобы создать новый экземпляр TokenResponse, когда мне это нужно. Опции

Google Authentication

private GoogleOAuth2AuthenticationOptions ConfigureGooglePlus() 
{ 

    var goolePlusOptions = new GoogleOAuth2AuthenticationOptions() 
    { 
     AccessType = "offline", 
     ClientId = "Xxxxxxx.apps.googleusercontent.com", 
     ClientSecret = "Yyyyyyyyyy", 
     Provider = new GoogleOAuth2AuthenticationProvider() 
     { 
      OnAuthenticated = context => 
      { 
       context.Identity.AddClaim(new System.Security.Claims.Claim("Google_AccessToken", context.AccessToken)); 

       if (context.RefreshToken != null) 
       { 
        context.Identity.AddClaim(new Claim("GoogleRefreshToken", context.RefreshToken)); 
       } 
       context.Identity.AddClaim(new Claim("GoogleUserId", context.Id)); 
       context.Identity.AddClaim(new Claim("GoogleTokenIssuedAt", DateTime.Now.ToBinary().ToString())); 
       var expiresInSec = (long)(context.ExpiresIn.Value.TotalSeconds); 
       context.Identity.AddClaim(new Claim("GoogleTokenExpiresIn", expiresInSec.ToString())); 


       return Task.FromResult(0); 
      } 
     }, 

     SignInAsAuthenticationType = DefaultAuthenticationTypes.ExternalCookie 
    }; 

    goolePlusOptions.Scope.Add("https://www.googleapis.com/auth/plus.login"); 
    goolePlusOptions.Scope.Add("https://www.googleapis.com/auth/plus.me"); 
    goolePlusOptions.Scope.Add("https://www.googleapis.com/auth/userinfo.email"); 

    return goolePlusOptions; 
} 

Как получить учетные данные (с помощью маркера информации "хранящийся" в качестве требования)