OktaClient with PrivateKey example from .pfx in dotnet SDK

How do I create an OktaClient using PrivateKey authorization in the dotnet SDK?

There are not any examples I can find in the documentation. I have a .pfx file and am able to create an X509Certificate2 from the file, but can not, for the life of me, figure out how to convert it to the format required by the JsonWebKeyConfiguration.

The only partial example I’ve found is from a unit test (https://github.com/okta/okta-sdk-dotnet/blob/ded2b51ce5534fa54d2099ce78bf674ba6978be4/src/Okta.Sdk.UnitTests/Internal/TestCryptoKeys.cs), but it’s already a serialized JWK.

What I’ve tried that doesn’t work, getting the error Something went wrong when creating the signed JWT. Verify your private key.:

var signingCert = new X509Certificate2("{{my_cert}}.pfx", "{{pass_phrase}}");
var privateKey = signingCert.GetRSAPrivateKey();
// Also tried this
// var privateKey = new X509SecurityKey(signingCert);
var jwk = Microsoft.IdentityModel.Tokens.JsonWebKeyConverter.ConvertFromX509SecurityKey(privateKey);
var jwkSerialized = JsonSerializer.Serialize(jwk);

but jwkSerialized looks like

    "AdditionalData": {},
    "Alg": null,
    "Crv": null,
    "D": null,
    "DP": null,
    "DQ": null,
    "E": null,
    "K": null,
    "KeyId": "{{hidden}}",
    "KeyOps": [],
    "Kid": "{{hidden}}",
    "Kty": "RSA",
    "N": null,
    "Oth": null,
    "P": null,
    "Q": null,
    "QI": null,
    "Use": null,
    "X": null,
    "X5c": [
    "X5t": "{{hidden}}",
    "X5tS256": null,
    "X5u": null,
    "Y": null,
    "KeySize": 0,
    "HasPrivateKey": false,
    "CryptoProviderFactory": {
        "CryptoProviderCache": {},
        "CustomCryptoProvider": null,
        "CacheSignatureProviders": true

Additionally, it’d be great if the private key could be passed to the client configuration rather then sending in a JSON blob as a string, having it converted to an object (JsonWebKeyConfiguration), then converted back to JSON (The latter steps happening under the hood). JsonWebKeyConfiguration should just accept a SecurityKey in its constructor IMO.

I finally made a post here and SO and then figured it out hours later. You have to pass the exportable flag when instantiating the certificate.

var cert = new X509Certificate2("{{my_cert}}.pfx", "{{pass_phrase}}", X509KeyStorageFlags.Exportable);
var privateKey = new RsaSecurityKey(cert.GetRSAPrivateKey());
var jwk = JsonWebKeyConverter.ConvertFromRSASecurityKey(privateKey);

var oktaClientConfig = new OktaClientConfiguration
    OktaDomain = "{{domain}}",
    ClientId = {{client_id}},
    AuthorizationMode = AuthorizationMode.PrivateKey,
    PrivateKey = new JsonWebKeyConfiguration(JsonSerializer.Serialize(jwk)),
    Scopes = new List<string> {"okta.users.manage"}

var oktaClient = new OktaClient(oktaClientConfig);

@stephen.hickey It is glad to know the issue is figured out. Thanks for providing the solution to dev forum. I’ll close this topic then.