我想在azurewebsites.net https上托管身份服务器4,但我不知道如何找到我的someapp.azurewebsites.net子域名的ssl证书,以便我可以将其用作指纹?甚至可以获得在azurewebsites.net子域上的webapp上运行的ssl证书吗?
答案 0 :(得分:0)
使用自签名证书用于与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.....
}
答案 1 :(得分:0)
使用自签名证书。由于Identity Server仅在内部使用证书,因此它们不是由受信任的CA签名并不重要,您不会将其呈现给其他人。我将签名证书存储在Azure Key Vault中作为序列化的秘密。密钥保险库非常便宜,但您必须缓存结果,它不适用于高流量。
请记住在网站,功能应用程序或其他正在检索值的其他内容上启用托管服务标识,并将这些标识添加到Key Vault SAS列表中,并具有对Secrets的读访问权。
[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
[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
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];
}