12

サービス アカウント経由で Google アナリティクスのデータを取得したいと考えています。アプリケーションを初めて起動すると、すべてが正しく機能し、データにアクセスできます。しかし、アプリケーションを 2 回目に起動すると、「指定されたパスが見つかりません」というエラーが表示されます。アイデアはありますか?ロックできると思いました。

これは私のソースコードです:

   public static String GetAccessToken(string clientIdEMail, string keyFilePath, String scope)
    {
        // certificate
        var certificate = new X509Certificate2(keyFilePath, "notasecret", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable);

        // header
        var header = new { typ = "JWT", alg = "RS256" };

        // claimset
        var times = GetExpiryAndIssueDate();
        var claimset = new
        {
            iss = clientIdEMail,
            scope = scope,
            aud = "https://accounts.google.com/o/oauth2/token",
            iat = times[0],
            exp = times[1],
        };

        JavaScriptSerializer ser = new JavaScriptSerializer();

        // encoded header
        var headerSerialized = ser.Serialize(header);
        var headerBytes = Encoding.UTF8.GetBytes(headerSerialized);
        var headerEncoded = Convert.ToBase64String(headerBytes);

        // encoded claimset
        var claimsetSerialized = ser.Serialize(claimset);
        var claimsetBytes = Encoding.UTF8.GetBytes(claimsetSerialized);
        var claimsetEncoded = Convert.ToBase64String(claimsetBytes);

        // input
        var input = headerEncoded + "." + claimsetEncoded;
        var inputBytes = Encoding.UTF8.GetBytes(input);

        // signiture
        var rsa = certificate.PrivateKey as RSACryptoServiceProvider;
        var cspParam = new CspParameters
        {
            KeyContainerName = rsa.CspKeyContainerInfo.KeyContainerName,
            KeyNumber = rsa.CspKeyContainerInfo.KeyNumber == KeyNumber.Exchange ? 1 : 2,
            Flags = CspProviderFlags.UseMachineKeyStore
        };
        var aescsp = new RSACryptoServiceProvider(1024,cspParam) { PersistKeyInCsp = false };
        var signatureBytes = aescsp.SignData(inputBytes, "SHA256");
        var signatureEncoded = Convert.ToBase64String(signatureBytes);

        // jwt
        var jwt = headerEncoded + "." + claimsetEncoded + "." + signatureEncoded;

        var client = new WebClient();
        client.Encoding = Encoding.UTF8;
        var uri = "https://accounts.google.com/o/oauth2/token";
        var content = new NameValueCollection();

        content["assertion"] = jwt;
        content["grant_type"] = "urn:ietf:params:oauth:grant-type:jwt-bearer";

        string response = Encoding.UTF8.GetString(client.UploadValues(uri, "POST", content));

        JsonGoogleResponse result = (ser.Deserialize<JsonGoogleResponse>(response));



        return result.access_token;
    }

そして、これはスタックです:

  à   System.Security.Cryptography.CryptographicException.ThrowCryptogaphicException(Int32 hr)
  à System.Security.Cryptography.SafeProvHandle._FreeCSP(IntPtr pProvCtx)
  à System.Security.Cryptography.SafeProvHandle.ReleaseHandle()
  à System.Runtime.InteropServices.SafeHandle.InternalFinalize()
  à System.Runtime.InteropServices.SafeHandle.Dispose(Boolean disposing)
  à System.Runtime.InteropServices.SafeHandle.Finalize()
4

3 に答える 3

43

IIS で実行している場合は、アプリケーション プールの詳細設定で [ユーザー プロファイルの読み込み] を True に設定して、ファイル名とパスワードで証明書を読み込めるようにする必要があります。

于 2016-08-23T18:34:17.317 に答える
5

だから、私はまったく同じ問題を抱えていました。私はほぼ4時間それを解こうとしました。

キーに渡されたパスに問題がありました。パスが「key.p12」で、キーがexeファイルと同じディレクトリにあるGoogleサンプルコンソールアプリケーションのコードを使用したためです。

そしてMVCアプリケーションを作ろうと思った時、仮想サーバーパスのルートが「key.p12」のように呼び出せないことに気づきませんでした。

解決

キーへのパスを再確認します。MVC アプリケーション (または別の ASP Web) の場合は、キー ファイルをルートに追加し、コードでServer.MapPath("key.p12")を使用してキーを呼び出します。

于 2013-08-08T13:52:35.697 に答える