c# - 系统找不到使用 X509Certificate2 指定的文件来连接 Azure 服务器中的 Google OAuth2.0

标签 c# azure x509certificate2

我使用此代码连接到 Google OAuth2.0,并且使用 C# 库。

using (var tImpersonationContext = new ImpersonationContext(ConfigurationManager.AppSettings["ImpersonationDomain"], ConfigurationManager.AppSettings["ImpersonationUser"], ConfigurationManager.AppSettings["ImpersonationPassword"]))
{
    string[] tScopes = new string[] { AnalyticsService.Scope.Analytics };
    var tKeyFilePath = Path.Combine(System.IO.Path.GetDirectoryName(Environment.GetCommandLineArgs()[0]), String.Format("GoogleCertificates\\{0}", this.OAuthKeyName));
    var tServiceAccountEmail = this.OAuthServiceAccountEmail;

    //loading the Key file
    var tCertificate = new X509Certificate2(tKeyFilePath, this.OAuthKeyPassword, X509KeyStorageFlags.Exportable);
    var tCredential = new ServiceAccountCredential(new ServiceAccountCredential.Initializer(tServiceAccountEmail)
    {
        Scopes = tScopes
    }.FromCertificate(tCertificate));

    if (tCredential.RequestAccessTokenAsync(CancellationToken.None).Result)
    {
        this.SessionToken = tCredential.Token.AccessToken;
    }
}

在我的开发环境中,一切都运行得非常完美,但是当我将应用程序移动到我的 Azure 服务器时,我收到了此错误:

The system cannot find the file specified.

当我尝试执行这一行时:

var tCertificate = new X509Certificate2(tKeyFilePath, this.OAuthKeyPassword, X509KeyStorageFlags.Exportable);

我确信路径是正确的,事实上,如果我将路径复制并粘贴到文件资源管理器中,导入证书的向导就会启动。

我确信模拟正在工作,因为该行已执行。

我尝试将其更改为:

var tCertificate = new X509Certificate2(tKeyFilePath, this.OAuthKeyPassword, X509KeyStorageFlags.MachineKeySet);

或者这个:

var tCertificate = new X509Certificate2(tKeyFilePath, this.OAuthKeyPassword, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.UserKeySet | X509KeyStorageFlags.UserProtected | X509KeyStorageFlags.DefaultKeySet);

什么都不起作用,事实上,我从该网站的其他问题中尝试过的所有内容都不起作用。

如果它有帮助,我假装在计划的任务中使用一个 Windows 应用程序,以从 Google Analytics 获取数据。

有人知道为什么无法在 Azure 服务器中工作吗?

提前致谢。

更新

我尝试安装证书,并将代码更改为:

var tCertificate = new X509Certificate2(tKeyFilePath, this.OAuthKeyPassword, X509KeyStorageFlags.MachineKeySet);

但现在我收到此错误:

Key not valid for use in specified state.

最佳答案

我已经更改了所有代码和方法,现在正在工作。

首先,您必须在受信任的根证书颁发机构内的 MMC 管理器中的证书下安装证书,并且必须将其设置为本地计算机。

然后您只需使用此代码:

X509Store tCertStore = new X509Store(StoreName.Root, StoreLocation.LocalMachine);
tCertStore.Open(OpenFlags.ReadOnly);
X509Certificate2Collection tCertCollection = tCertStore.Certificates.Find(X509FindType.FindByThumbprint, this.OAuthKeyFingerprint, false);

// Get the first cert with the thumbprint
if (tCertCollection.Count > 0)
{
    // header
    var tHeader = new { typ = "JWT", alg = "RS256" };

    // claimset
    var tTimes = GetExpiryAndIssueDate();
    var tClaimset = new
    {
        iss = this.OAuthServiceAccountEmail,
        scope = "https://www.googleapis.com/auth/analytics",
        aud = "https://www.googleapis.com/oauth2/v3/token",
        iat = tTimes[0],
        exp = tTimes[1],
    };

    JavaScriptSerializer ser = new JavaScriptSerializer();

    // encoded header
    var tHeaderSerialized = ser.Serialize(tHeader);
    var tHeaderBytes = Encoding.UTF8.GetBytes(tHeaderSerialized);
    var tHeaderEncoded = Convert.ToBase64String(tHeaderBytes);

    // encoded claimset
    var tClaimsetSerialized = ser.Serialize(tClaimset);
    var tClaimsetBytes = Encoding.UTF8.GetBytes(tClaimsetSerialized);
    var tClaimsetEncoded = Convert.ToBase64String(tClaimsetBytes);

    // input
    var tInput = tHeaderEncoded + "." + tClaimsetEncoded;
    var tInputBytes = Encoding.UTF8.GetBytes(tInput);

    X509Certificate2 tCertificate = tCertCollection[0];

    // signiture
    var tRSA = tCertificate.PrivateKey as RSACryptoServiceProvider;

    var tCspParam = new CspParameters
    {
        KeyContainerName = tRSA.CspKeyContainerInfo.KeyContainerName,
        KeyNumber = tRSA.CspKeyContainerInfo.KeyNumber == KeyNumber.Exchange ? 1 : 2,
        Flags = CspProviderFlags.UseMachineKeyStore
    };
    var tAesCsp = new RSACryptoServiceProvider(1024, tCspParam) { PersistKeyInCsp = true };
    var tSignatureBytes = tAesCsp.SignData(tInputBytes, "SHA256");
    var tSignatureEncoded = Convert.ToBase64String(tSignatureBytes);

    // jwt
    var tJWT = tHeaderEncoded + "." + tClaimsetEncoded + "." + tSignatureEncoded;

    HttpClient tClient = new HttpClient();

    Dictionary<string, string> tPost = new Dictionary<string, string>
        {
            {"assertion", tJWT},
            {"grant_type", "urn:ietf:params:oauth:grant-type:jwt-bearer"}
        };

    FormUrlEncodedContent tContent = new FormUrlEncodedContent(tPost);

    var tURI = "https://www.googleapis.com/oauth2/v3/token";

    HttpResponseMessage tResult = tClient.PostAsync(tURI, tContent).Result;
    TokenResponse tTokenObject = JsonConvert.DeserializeObject<TokenResponse>(tResult.Content.ReadAsStringAsync().Result);

    this.SessionToken = tTokenObject.access_token;
}

tCertStore.Close();

我希望这对某人有帮助。

祝你编码愉快。

关于c# - 系统找不到使用 X509Certificate2 指定的文件来连接 Azure 服务器中的 Google OAuth2.0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31857930/

相关文章:

c# - 无法加载一种或多种请求的类型。检索 LoaderExceptions 属性以获取更多信息。与实体数据源

c# - ModelBinder反序列化任意json

c# - 在mvvm中的内容控件中更改用户控件

c# - 在 Azure Function 中找不到 EF 的 Getter 方法

powershell - 新-AzureADPolicy : Error occurred while executing NewPolicy

C#枚举TLS证书支持的所有主机名

c# - 在 .Net 中使用 p12/pfx 文件签署数据 - 发生内部证书链接错误

c# - 格式化 - 添加逗号,2 位小数到单元格值 vb.net excel interop

.net - Azure CDN 缓存,图像未立即更新?

c# - 我应该将 x509 证书的哪一部分存储在数据库中以查找用户?