C# Google将OAuth2与服务帐户协调
我有一个C#控制台应用程序,带有开放式身份验证和服务帐户C# Google将OAuth2与服务帐户协调,c#,.net,google-api,google-oauth,google-api-dotnet-client,C#,.net,Google Api,Google Oauth,Google Api Dotnet Client,我有一个C#控制台应用程序,带有开放式身份验证和服务帐户 private const string SERVICE_ACCOUNT_EMAIL = "XXX@developer.gserviceaccount.com"; private const string SERVICE_ACCOUNT_PKCS12_FILE_PATH = @"<path-to-private-key-file>\YYY-privatekey.p12"; private const string GOOGLE
private const string SERVICE_ACCOUNT_EMAIL = "XXX@developer.gserviceaccount.com";
private const string SERVICE_ACCOUNT_PKCS12_FILE_PATH = @"<path-to-private-key-file>\YYY-privatekey.p12";
private const string GOOGLE_COORDINATE_TEAM_ID = "ZZZ";
private CoordinateService BuildService()
{
X509Certificate2 certificate = new X509Certificate2(SERVICE_ACCOUNT_PKCS12_FILE_PATH, "notasecret", X509KeyStorageFlags.Exportable);
var provider = new AssertionFlowClient(GoogleAuthenticationServer.Description, certificate){
ServiceAccountId = SERVICE_ACCOUNT_EMAIL,
Scope = CoordinateService.Scopes.Coordinate.GetStringValue()
};
var auth = new OAuth2Authenticator<AssertionFlowClient>(provider, AssertionFlowClient.GetState);
return new CoordinateService(new BaseClientService.Initializer(){
Authenticator = auth
});
}
//some code that retrieves data from coordinate service
public void DoSomething()
{
CoordinateService service = BuildService();
var response = service.Jobs.List(GOOGLE_COORDINATE_TEAM_ID).Fetch();
...
}
我读过一些文章,建议更改本地服务器时间,以便与谷歌誓言服务器时间相匹配。但在把时间移到一边和另一边之后,问题仍然是一样的。
你能告诉我为什么会这样吗?
谢谢大家的回复 服务帐户不能与坐标API一起使用。[这是因为坐标API要求经过身份验证的API用户拥有坐标许可证,但无法将坐标许可证附加到服务帐户] 您可以改为使用web服务器流,请查找下面的示例 确保更新下面的代码,其中有包含“要更新”的注释
使用系统;
使用系统诊断;
使用System.Collections.Generic;
使用DotNetOpenAuth.OAuth2;
使用Google.api.Authentication.OAuth2;
使用Google.api.Authentication.OAuth2.DotNetOpenAuth;
使用Google.api.Coordinate.v1;
使用Google.api.Coordinate.v1.Data;
名称空间Google.api.Samples.CoordinationAuth2
{
///
///此示例演示了OAuth2服务的最简单用例。
///这里提供的模式可以应用于每个需要身份验证的请求。
///
公共类程序Web服务器
{
公共静态void Main(字符串[]args)
{
//要更新,可在坐标应用程序URL中找到
String TEAM_ID=“jskdQ--xKjFiFqLO-IpIlg”;
//注册验证器。
var provider=新的WebServerClient(GoogleAuthenticationServer.Description);
//要更新,可以在API控制台中找到。
provider.ClientIdentifier=“335858260352.apps.googleusercontent.com”;
//要更新,可以在API控制台中找到。
provider.ClientSecret=“yAMx sR[trunched]fX9ghtPRI”;
var auth=新的OAuth2Authenticator(提供者,GetAuthorization);
//创建服务。
var service=new CoordinateService(new BaseClientService.Initializer()
{
验证器=auth
});
//为可选参数创建作业资源https://developers.google.com/coordinate/v1/jobs#resource
Job jobBody=新作业();
jobBody.Kind=“坐标#作业”;
State=newjobstate();
jobBody.State.Kind=“坐标#作业状态”;
jobBody.State.Assignee=”user@example.com";
//创建作业
JobsResource.InsertRequest ins=service.Jobs.Insert(jobBody,团队ID,“我家”,“51”,“0”,“使用.Net客户端库创建此作业”);
作业结果=ins.Fetch();
//显示响应
Console.WriteLine(“作业ID:”);
Console.WriteLine(results.Id.ToString());
Console.WriteLine(“按任意键继续”);
Console.ReadKey();
}
私有静态IAAuthorizationState GetAuthorization(WebServerClient客户端)
{
IAAuthorizationState=新授权状态(新[]{”https://www.googleapis.com/auth/coordinate" });
//已脱机检索刷新令牌
//在实际应用程序中,必须安全地存储该令牌,因为该令牌
//允许接受OAuth2流的用户访问坐标范围内的所有用户数据
//更新(有关说明,请参见下面的示例)
state.RefreshToken=“1/0KuRg-fh9yO[截断]yNVQcXcVYlfXg”;
返回状态;
}
}
}
可以使用OAuth2检索刷新令牌:
- 在API控制台中,添加OAuth操场URL作为授权URL 重定向URI(当我们在 OAuth游乐场(下图)
- 转到OAuth游乐场,在已验证API用户身份的浏览器会话中(该用户需要有坐标许可证)确保提供 您拥有OAuth2客户端ID(设置>使用您自己的OAuth凭据)。 否则,您的刷新令牌将绑定到OAuth2游乐场的 内部OAuth2客户端ID,当您要使用时将被拒绝 使用您自己的客户端ID刷新令牌以获取访问令牌
- 使用步骤1中的范围, 在步骤2中点击“授权API”,点击“交换授权代码” “代币”
- 复制代码中的刷新令牌。保持安全
- 此刷新令牌不会过期,因此您的应用程序将保持身份验证
使用系统;
使用系统诊断;
使用System.Collections.Generic;
使用DotNetOpenAuth.OAuth2;
使用Google.api.Authentication.OAuth2;
使用Google.api.Authentication.OAuth2.DotNetOpenAuth;
使用Google.api.Coordinate.v1;
使用Google.api.Coordinate.v1.Data;
名称空间Google.api.Samples.CoordinationAuth2
{
///
///此示例演示了OAuth2服务的最简单用例。
///这里提供的模式可以应用于每个需要身份验证的请求。
///
公共类程序Web服务器
{
公共静态void Main(字符串[]args)
{
//要更新,可在坐标应用程序URL中找到
String TEAM_ID=“jskdQ--xKjFiFqLO-IpIlg”;
//注册验证器。
{
"error" : "invalid_grant"
}
using System;
using System.Diagnostics;
using System.Collections.Generic;
using DotNetOpenAuth.OAuth2;
using Google.Apis.Authentication.OAuth2;
using Google.Apis.Authentication.OAuth2.DotNetOpenAuth;
using Google.Apis.Coordinate.v1;
using Google.Apis.Coordinate.v1.Data;
namespace Google.Apis.Samples.CoordinateOAuth2
{
/// <summary>
/// This sample demonstrates the simplest use case for an OAuth2 service.
/// The schema provided here can be applied to every request requiring authentication.
/// </summary>
public class ProgramWebServer
{
public static void Main (string[] args)
{
// TO UPDATE, can be found in the Coordinate application URL
String TEAM_ID = "jskdQ--xKjFiFqLO-IpIlg";
// Register the authenticator.
var provider = new WebServerClient (GoogleAuthenticationServer.Description);
// TO UPDATE, can be found in the APIs Console.
provider.ClientIdentifier = "335858260352.apps.googleusercontent.com";
// TO UPDATE, can be found in the APIs Console.
provider.ClientSecret = "yAMx-sR[truncated]fX9ghtPRI";
var auth = new OAuth2Authenticator<WebServerClient> (provider, GetAuthorization);
// Create the service.
var service = new CoordinateService(new BaseClientService.Initializer()
{
Authenticator = auth
});
//Create a Job Resource for optional parameters https://developers.google.com/coordinate/v1/jobs#resource
Job jobBody = new Job ();
jobBody.Kind = "Coordinate#job";
jobBody.State = new JobState ();
jobBody.State.Kind = "coordinate#jobState";
jobBody.State.Assignee = "user@example.com";
//Create the Job
JobsResource.InsertRequest ins = service.Jobs.Insert (jobBody, TEAM_ID, "My Home", "51", "0", "Created this Job with the .Net Client Library");
Job results = ins.Fetch ();
//Display the response
Console.WriteLine ("Job ID:");
Console.WriteLine (results.Id.ToString ());
Console.WriteLine ("Press any Key to Continue");
Console.ReadKey ();
}
private static IAuthorizationState GetAuthorization (WebServerClient client)
{
IAuthorizationState state = new AuthorizationState (new[] { "https://www.googleapis.com/auth/coordinate" });
// The refresh token has already been retrieved offline
// In a real-world application, this has to be stored securely, since this token
// gives access to all user data on the Coordinate scope, for the user who accepted the OAuth2 flow
// TO UPDATE (see below the sample for instructions)
state.RefreshToken = "1/0KuRg-fh9yO[truncated]yNVQcXcVYlfXg";
return state;
}
}
}