2017-04-11 4 views
2

Ich habe einen WebJob, der ein JWT-Token erstellen muss, um mit einem externen Dienst zu sprechen. Der folgende Code funktioniert, wenn ich die WebJob auf meinem lokalen Rechner laufen:Wie kann ich ein JWT-Token auf einem Azure-WebJob signieren, ohne eine CryptographicException zu erhalten?

public static string SignES256(byte[] p8Certificate, object header, object payload) 
{ 
    var headerString = JsonConvert.SerializeObject(header); 
    var payloadString = JsonConvert.SerializeObject(payload); 

    CngKey key = CngKey.Import(p8Certificate, CngKeyBlobFormat.Pkcs8PrivateBlob); 
    using (ECDsaCng dsa = new ECDsaCng(key)) 
    { 
     dsa.HashAlgorithm = CngAlgorithm.Sha256; 
     var unsignedJwtData = Base64UrlEncoder.Encode(Encoding.UTF8.GetBytes(headerString)) + "." + Base64UrlEncoder.Encode(Encoding.UTF8.GetBytes(payloadString)); 
     var signature = dsa.SignData(Encoding.UTF8.GetBytes(unsignedJwtData)); 
     return unsignedJwtData + "." + Base64UrlEncoder.Encode(signature); 
    } 
} 

Allerdings, wenn ich meine WebJob zu Azure bereitstellen, erhalte ich die folgende Ausnahme:

Microsoft.Azure.WebJobs.Host .FunctionInvocationException: Ausnahme beim Ausführen der Funktion: NotificationFunctions.QueueOperation ---> System.Security.Cryptography.CryptographicException: Das System kann die angegebene Datei nicht finden. bei System.Security.Cryptography.NCryptNative.ImportKey (SafeNCryptProviderHandle Anbieter Byte [] Keyblob, String-Format) bei System.Security.Cryptography.CngKey.Import (Byte [] Keyblob, CngKeyBlobFormat Format, CngProvider Provider)

Es sagt, dass es eine bestimmte Datei nicht finden kann, aber die Parameter, die ich übergebe, gucken nicht auf einen Speicherort, sie sind im Speicher. Von dem, was ich gesammelt habe, kann es eine Art von Kryptografieeinstellung geben, die ich aktivieren muss, um die CngKey.Import-Methode verwenden zu können, aber ich kann keine Einstellungen im Azure-Portal finden, die damit in Verbindung stehen.

Ich habe auch versucht, mit JwtSecurityTokenHandler, aber es scheint nicht zu handhaben, die ES256 Hashing-Algorithmus, den ich verwenden muss (obwohl es in der JwtAlgorithms-Klasse als ECDSA_SHA256 verwiesen wird).

Irgendwelche Vorschläge würden geschätzt!

UPDATE

Es scheint, dass CngKey.Import kann tatsächlich das Zertifikat irgendwo zu speichern versuchen, die nicht zugänglich auf Azure ist. Ich brauche es nicht gespeichert, also wenn es eine bessere Möglichkeit gibt, auf das Zertifikat im Speicher zuzugreifen oder es in eine andere Art von Zertifikat zu konvertieren, das einfacher zu verwenden wäre, würde das funktionieren.

UPDATE 2

Dieses Problem kann nicht auf Azure Web Apps IIS zusammenhängen Einstellung das Benutzerprofil laden als here erwähnt. Ich habe dies aktiviert, indem ich WEBSITE_LOAD_USER_PROFILE = 1 in den Azure-Portal-App-Einstellungen festgelegt habe. Ich habe mit diesem Update versucht, den Code sowohl über den WebJob als auch über die Web App in Azure auszuführen, bekomme aber immer noch den gleichen Fehler.

+0

Wird derselbe Fehler angezeigt, wenn Sie versuchen, ihn lokal auf Ihrem Dev-Rechner auszuführen? – Niels

+0

Nein, lokal auf meinem Computer läuft es wie ein WebJob wie erwartet, es wird keine Ausnahme ausgelöst. – lehn0058

+0

Wo haben Sie Ihr Zertifikat importiert? Ich meine auf Azure – Thomas

Antwort

1

Ich benutzte einen Decompiler, um einen Blick unter die Haube zu werfen, was die CngKey.Import-Methode tatsächlich tat. Es sieht so aus, als ob es versucht, das Zertifikat, das ich verwende, in den "Microsoft Software Key Storage Provider" einzufügen. Ich brauche das eigentlich nicht, ich muss nur den Wert des Zertifikats lesen, aber es sieht nicht so aus, als wäre das möglich.

Sobald ich festgestellt habe, dass ein Zertifikat in einem Geschäft irgendwo auf der Maschine eingefügt wird, begann ich darüber nachzudenken, wie schlecht von einem Sicherheitsstandpunkt zu denken wäre, wenn Ihre Azure Web App in einer gemeinsamen Umgebung ausgeführt würde tut für die freien und geteilten Stufen. Sicher genug, meine VM war auf der Shared-Ebene. Durch die Skalierung auf die Basisebene wurde dieses Problem behoben.

Verwandte Themen