.NET Core用X.509证书调用Google AdMob API时OAuth 2.0 JWT令牌错误
调用Google AdMob API时的未授权认证错误
我正尝试调用Google AdMob API服务,该API要求采用OAuth 2.0服务到服务集成流程,需分两步操作:
- 创建本地签名JWT并发送至Google
- 获取令牌以查询API
但测试手动创建JWT和使用官方库两种方式时,均抛出相同的未授权错误:
“服务admob抛出异常。HttpStatusCode为Unauthorized。请求缺少必需的认证凭据。预期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负载中的额外值(如"Kid"),无效果
- 使用官方发布的Google.Apis.Auth和Google.Apis.AdMob.v1库
- 手动创建JWT从Google OAuth令牌端点获取访问令牌
内容的提问来源于stack exchange,提问作者Jose Cordero
相关产品推荐
相关产品推荐

