Google Oauth错误:应设置至少一个客户端机密(已安装或Web)

时间:2015-03-03 06:59:12

标签: c# oauth-2.0 google-oauth

我正在使用Google的Oauth 2.0通过我们的服务器将视频上传到Youtube。 我的客户ID是"服务帐户"。我下载了json密钥并将其添加到我的解决方案中。

以下是相关代码:

 private async Task Run(string filePath)
        {
            UserCredential credential;
            var keyUrl = System.Web.HttpContext.Current.Server.MapPath("~/content/oauth_key.json");
            using (var stream = new FileStream(keyUrl, FileMode.Open, FileAccess.Read))
            {
                credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
                    GoogleClientSecrets.Load(stream).Secrets,
                    // This OAuth 2.0 access scope allows an application to upload files to the
                    // authenticated user's YouTube channel, but doesn't allow other types of access.
                    new[] { YouTubeService.Scope.YoutubeUpload },
                    "user",
                    CancellationToken.None
                );
            }

            var youtubeService = new YouTubeService(new BaseClientService.Initializer()
            {
                HttpClientInitializer = credential,
                ApplicationName = Assembly.GetExecutingAssembly().GetName().Name
            });

当我运行它时,我收到此错误:应设置至少一个客户机密码(已安装或Web)。

然而,在我的json中没有"客户端秘密":

{
  "private_key_id": "9d98c06b3e730070806dcf8227578efd0ba9989b",
  "private_key": "-----BEGIN PRIVATE KEY-----\nMIICdQIBADANBgkqhk etc,
  "client_email": "546239405652-8igo05a5m8cutggehk3rk3hspjfm3t04@developer.gserviceaccount.com",
  "client_id": "546239405652-8igo05a5m8cutggehk3rk3hspjfm3t04.apps.googleusercontent.com",
  "type": "service_account"
}

所以我认为我忽视了一些事情。 也许我无法使用"服务帐户" ?不知道......

3 个答案:

答案 0 :(得分:22)

使用json文件的解决方案非常相似。

以下是使用VisionService文件创建的GoogleCredential对象json创建ServiceAccountCredential的示例。

GoogleCredential credential;
using (var stream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
{
    credential = GoogleCredential.FromStream(stream)
        .CreateScoped(VisionService.Scope.CloudPlatform);
}

var service = new VisionService(new BaseClientService.Initializer()
{
    HttpClientInitializer = credential,
    ApplicationName = "my-app-name",
});

此示例需要两个NuGet个包:

Google.Apis.Vision.v1  
Google.Apis.Oauth2.v2

答案 1 :(得分:8)

我设法获得了一个服务帐户来处理P12文件,但是想知道如何使用JSON文件,或者只是从JSON文件中创建值来创建证书。

获取令牌

//
// using Java 8 syntax, but this is not a hard requirement
//
final Once<Integer> i = Once<>();
i.set(100);
i.get();    // returns 100
// i.set(200) would throw an IllegalStateException

final Lazy<Integer> j = Lazy<>(() -> i);
j.get();    // returns 100

这就是我使用我得到的令牌的方式

    private static String GetOAuthCredentialViaP12Key()
    {
        const string serviceAccountEmail = SERVICE_ACCOUNT_EMAIL;
        var certificate = new X509Certificate2(SERVICE_ACCOUNT_PKCS12_FILE_PATH, "notasecret", X509KeyStorageFlags.Exportable);

        var scope = DriveService.Scope.Drive + " https://spreadsheets.google.com/feeds";
        var credential = new ServiceAccountCredential( new ServiceAccountCredential.Initializer(serviceAccountEmail)
                                                       {
                                                            Scopes  = new[] { scope }
                                                       }.FromCertificate(certificate) );

        if (credential.RequestAccessTokenAsync(CancellationToken.None).Result == false)
        {

            return null;
        }

        return credential.Token.AccessToken;
    }

答案 2 :(得分:4)

不是C#的专家,但看起来您尝试使用服务帐户来执行OAuth2 Web服务器流,这应该不起作用。 您可能希望使用ServiceAccountCredential代替。 有关不同Google OAuth2流程的详细信息,请参阅web serverservice account等文档。