【问题标题】:Identityserver4 with azurewebsites.net domain - how to get ssl thumbprint具有 azurewebsites.net 域的 Identityserver4 - 如何获取 ssl 指纹
【发布时间】:2018-03-03 05:52:31
【问题描述】:

我想在 azurewebsites.net https 上托管身份服务器 4,但我不确定如何找到我的 someapp.azurewebsites.net 子域的 ssl 证书,以便我可以将其用作指纹?甚至有可能获得在 azurewebsites.net 子域的 webapp 上运行的 ssl 证书吗?

【问题讨论】:

  • 您要使用证书进行签名吗?
  • 身份服务器可以,但我没有找到获取方法

标签: c# azure-web-app-service identityserver4


【解决方案1】:

使用自签名证书。由于 Identity Server 仅在内部使用证书,因此它们没有由受信任的 CA 签名并不重要,您不会将它们呈现给其他人。我将我的签名证书作为序列化机密存储在 Azure Key Vault 中。 Key Vault 非常便宜,但您必须缓存结果,它不适合高流量。

记得在网站、Function App 或任何其他检索值的设备上启用托管服务标识,并将这些添加到 Key Vault SAS 列表中,并对 Secrets 具有读取权限。

Powershell:创建签名证书

[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:将证书上传到 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

线程安全的 Key Vault 缓存

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;
    }
}

反序列化证书的检索

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];
}

【讨论】:

    【解决方案2】:

    使用自签名证书用于 IdentityServer4 令牌签名的一种方法是将证书与应用程序一起存储在“wwwroot”文件夹下。

    您可以使用 OpenSSL 生成自签名证书。

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

    然后在“Startup.cs”类/文件中加载证书。

    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.....
    }
    

    【讨论】:

    • 我明白了,但是如何获得 azurewebsites.net 证书?
    • 所以您想要 Azure Web 应用上的 SSL 证书来验证您的应用/域名?
    • 我想使用 azure 的默认证书进行身份服务器身份验证。为 azurewebsites.net 域制作的证书。
    • 我认为您不能,因为我们无权访问该证书。最好的办法是创建一个自签名证书并按照我的建议使用它。
    • 域与令牌签名和验证证书无关。该证书仅由 IS4 在内部使用。 SSL 证书可以重复使用(但不能以您要求的方式访问),但从技术上讲,签名证书的设置方式会有所不同。我所有的证书和设置(如连接字符串)都在 Key Vault 中,每月只需几美分...
    猜你喜欢
    • 2017-02-20
    • 1970-01-01
    • 2015-05-11
    • 2012-10-14
    • 1970-01-01
    • 2013-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多