使用 .NET Core 和 X.509 证书的 Google API 的错误 OAuth 2.0 JWT 令牌

问题描述 投票:0回答:1

我正在尝试向 Google APIs AdMob 服务发出请求。此 API 需要新的 OAuth 2.0 身份验证过程,该过程用于服务到服务的集成,是一个两步过程:1) 创建本地并签名的 JWT 并将其发送给 Google 2) 检索令牌以查询 API。我一直在测试手动创建 JWT 并使用官方库,但他们最终抛出了同样的错误:

admob 服务抛出异常。HttpStatusCode 未授权。请求缺少必需的身份验证凭据。需要 OAuth 2 访问令牌、登录 cookie 或其他有效的身份验证凭据。

使用官方库的代码

// path to the .p12 certificate
var privateKeyFilePath = Path.Combine(X509_KEY_FILE_NAME);
var certificate = new X509Certificate2(privateKeyFilePath, "MySecret", X509KeyStorageFlags.Exportable);
CertificateCredentials = new ServiceAccountCredential(new ServiceAccountCredential.Initializer(emailAccountId)
{
    ProjectId = "MyProjectId",
    Scopes = new[] { AdMobService.Scope.AdmobReadonly },
}.FromCertificate(certificate));
...
var adMobService = new AdMobService(new BaseClientService.Initializer()
{
    HttpClientInitializer = CertificateCredentials,
    ApplicationName = "MyProjectId",
});
// line that throws the error
var accountsResponse = await adMobService.Accounts.List().ExecuteAsync(cancellationToken);

var account = accountsResponse.Account.FirstOrDefault();

使用本地签名令牌的代码:


// we reuse X509 loaded previously
var signingCredentials = new SigningCredentials(new RsaSecurityKey(certificate.GetRSAPrivateKey()), SecurityAlgorithms.RsaSha256);

var jwtHeader = new JwtHeader(signingCredentials)
    {
        { "kid", kid }
    };

var jwtPayload = new JwtPayload(
        issuer: emailAccountId,
        audience: GoogleAuthConsts.TokenUrl,
        claims: new List<Claim>()
        {
            new Claim("scope", AdMobService.Scope.AdmobReadonly),
        },
        notBefore: null,
        expires: DateTime.Now.AddHours(1),
        issuedAt: DateTime.Now);

var handler = new JwtSecurityTokenHandler();
var jwt = handler.WriteToken(new JwtSecurityToken(jwtHeader, jwtPayload));

var httpClient = new HttpClient();
var parameters = new Dictionary<string, string> {
        { "grant_type", "urn:ietf:params:oauth:grant-type:jwt-bearer" },
        { "assertion", jwt }
    };
var httpContent = new FormUrlEncodedContent(parameters);

var response = await httpClient.PostAsync(GoogleAuthConsts.OidcTokenUrl, httpContent, cancellationToken);
var responseContent = await response.Content.ReadAsStringAsync(cancellationToken);

var TokenResponse = Newtonsoft.Json.JsonConvert.DeserializeObject<TokenResponse>(responseContent);

var httpClientAdMob = new HttpClient();
httpClientAdMob.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", TokenResponse.AccessToken);
var responseAdMob = await httpClientAdMob.GetAsync("https://admob.googleapis.com/v1/accounts", cancellationToken);

if (responseAdMob.IsSuccessStatusCode)
{
// line that throws the error
    var contentAdMob = await responseAdMob.Content.ReadAsStringAsync(cancellationToken);
}

通过删除 JWT Payload 的额外值,因为“Kid”似乎没有影响。

我尝试了 Google.Apis.AuthGoogle.Apis.AdMob.v1 库的官方版本。除了手动创建 JWT 以从 Google OAuth 的令牌 端点检索访问令牌。

c# admob google-oauth service-accounts google-api-dotnet-client
1个回答
0
投票

如果您检查文档授权,您会注意到它声明

需要使用Oauth2服务账号授权不支持

© www.soinside.com 2019 - 2024. All rights reserved.