Identityserver4 with azurewebsites.net domain - how to get ssl thumbprint

血红的双手。 提交于 2019-12-06 13:32:28

问题


I want to host identity server 4 on azurewebsites.net https but I am not sure how to find ssl certificate of my someapp.azurewebsites.net sub domain so I can use it as thumbprint? Is that even possible to obtain ssl certificate that is running on your webapp on azurewebsites.net subdomain?


回答1:


One way to use a self-signed certificate to use for token signing with IdentityServer4 is to store the certificate with the application under the 'wwwroot' folder.

You can use OpenSSL to generate a self-signed certificate.

openssl req -x509 -newkey rsa:4096 -sha256 -nodes -keyout example.key -out example.crt -subj "/CN=example.com" -days 3650

Then load the certificate in the 'Startup.cs' class/file.

public void ConfigureServices(IServiceCollection services)
{
        .....other code .....

        var fileName = Path.Combine(env.WebRootPath, "YOUR_FileName" );            

        if (!File.Exists(fileName))
        {
            throw new FileNotFoundException("Signing Certificate is missing!");
        }

        var cert = new X509Certificate2(fileName, "Your_PassPhrase" );

        services.AddIdentityServer().AddSigningCredential(cert)

        ...other code.....
}



回答2:


Use self-signed certificates. Since Identity Server only uses the certs internally, it doesn't matter that they aren't signed by a trusted CA, you aren't presenting them to others. I store my signing certificates in Azure Key Vault as serialized Secrets. Key Vault is very inexpensive but you have to cache the results, it isn't meant for high traffic.

Remember to enable Managed Service Identity on the website, Function App, or whatever else is retrieving the values, and add those to the Key Vault SAS list with read-access to Secrets.

Powershell: Create Signing Certificate

[CmdletBinding()]
param(
    [Parameter(Mandatory=$true)][string]$password = "",
    [Parameter(Mandatory=$true)][string]$rootDomain = ""
)

$cwd = Convert-Path .
$sCerFile = "$cwd\token_signing.cer"
$sPfxFile = "$cwd\token_signing.pfx"
$vCerFile = "$cwd\token_validation.cer"
$vPfxFile = "$cwd\token_validation.pfx"

# abort if files exist
if((Test-Path($sPfxFile)) -or (Test-Path($sCerFile)) -or (Test-Path($vPfxFile)) -or (Test-Path($vCerFile)))
{
    Write-Warning "Failed, token_signing or token_validation files already exist in current directory."
    Exit
}

function Get-NewCert ([string]$name)
{
    New-SelfSignedCertificate `
        -Subject $rootDomain `
        -DnsName $rootDomain `
        -FriendlyName $name `
        -NotBefore (Get-Date) `
        -NotAfter (Get-Date).AddYears(10) `
        -CertStoreLocation "cert:CurrentUser\My" `
        -KeyAlgorithm RSA `
        -KeyLength 4096 `
        -HashAlgorithm SHA256 `
        -KeyUsage DigitalSignature, KeyEncipherment, DataEncipherment `
        -Type Custom,DocumentEncryptionCert `
        -TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.1")
}

$securePass = ConvertTo-SecureString -String $password -Force -AsPlainText

# token signing certificate
$cert = Get-NewCert("IdentityServer Token Signing Credentials")
$store = 'Cert:\CurrentUser\My\' + ($cert.ThumbPrint)  
Export-PfxCertificate -Cert $store -FilePath $sPfxFile -Password $securePass
Export-Certificate -Cert $store -FilePath $sCerFile
Write-Host "Token-signing thumbprint: " $cert.Thumbprint

# token validation certificate
$cert =  Get-NewCert("IdentityServer Token Validation Credentials")
$store = 'Cert:\CurrentUser\My\' + ($cert.ThumbPrint)  
Export-PfxCertificate -Cert $store -FilePath $vPfxFile -Password $securePass
Export-Certificate -Cert $store -FilePath $vCerFile
Write-Host "Token-validation thumbprint: " $cert.Thumbprint

Powershell: Upload Certificate to Azure Key Vault

[CmdletBinding()]
param(
    [Parameter(Mandatory=$true)][string]$password = "",
    [Parameter(Mandatory=$true)][string]$pfxFilename = "",
    [Parameter(Mandatory=$true)][string]$keyVaultName = "",
    [Parameter(Mandatory=$true)][string]$secretName = ""
)

$cwd = Convert-Path .
$pfxFile = "$cwd\$pfxFilename.pfx"

# abort when file not found
if(!(Test-Path($pfxFile)))
{
    Write-Warning "Failed, $pfxFilename.pfx not found $cwd"
    Exit
}

# force Azure login, if needed
function CheckLogin
{
    $needLogin = $true
    Try 
    {
        $content = Get-AzureRmContext
        if ($content) 
        {
            $needLogin = ([string]::IsNullOrEmpty($content.Account))
        } 
    } 
    Catch 
    {
        if ($_ -like "*Login-AzureRmAccount to login*") 
        {
            $needLogin = $true
        } 
        else 
        {
            throw
        }
    }

    if ($needLogin)
    {
        Login-AzureRmAccount
    }
}

CheckLogin

# load the PFX
$flag = [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable
$coll = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2Collection 
$coll.Import($pfxFile, $password, $flag)

# export to byte array
$type = [System.Security.Cryptography.X509Certificates.X509ContentType]::Pkcs12
$bytes = $coll.Export($type)

# base64 encode
$base64 = [System.Convert]::ToBase64String($bytes)
$value = ConvertTo-SecureString -String $base64 -AsPlainText –Force

# send it to Azure KeyVault
$type = 'application/x-pkcs12'
Set-AzureKeyVaultSecret -VaultName $keyVaultName -Name $secretName -SecretValue $value -ContentType $type

Thread-Safe Key Vault Cache

public class KeyVaultCache
{
    private KeyVaultClient _KeyVaultClient = null;
    public KeyVaultClient KeyVaultClient
    {
        get
        {
            if(_KeyVaultClient is null)
            {
                var provider = new AzureServiceTokenProvider();
                _KeyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(provider.KeyVaultTokenCallback));
            }
            return _KeyVaultClient;
        }
    }

    private ConcurrentDictionary<string, string> SecretsCache = new ConcurrentDictionary<string, string>(StringComparer.OrdinalIgnoreCase);
    public async Task<string> GetCachedSecret(string secretName)
    {
        if(!SecretsCache.ContainsKey(secretName))
        {
            var secretBundle = await KeyVaultClient.GetSecretAsync($"{AzureUris.KeyVaultSecrets}{secretName}").ConfigureAwait(false);
            SecretsCache.TryAdd(secretName, secretBundle.Value);
        }
        return SecretsCache.ContainsKey(secretName) ? SecretsCache[secretName] : string.Empty;
    }
}

Retreival of Deserialized Certificates

public async Task<X509Certificate2> TokenValidationCertificate() => PfxStringToCert(await cache.GetCachedSecret("x509-token-validation"));
public async Task<X509Certificate2> TokenSigningCertificate() => PfxStringToCert(await cache.GetCachedSecret("x509-token-signing"));

private X509Certificate2 PfxStringToCert(string pfx)
{
    var bytes = Convert.FromBase64String(pfx);
    var coll = new X509Certificate2Collection();
    coll.Import(bytes, null, X509KeyStorageFlags.Exportable);
    return coll[0];
}


来源:https://stackoverflow.com/questions/49075143/identityserver4-with-azurewebsites-net-domain-how-to-get-ssl-thumbprint

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!