Include the developer certificate by default, make it noop when environment != development
This commit is contained in:
parent
45f9780d32
commit
63f7f9a62c
|
|
@ -44,15 +44,20 @@ namespace Microsoft.AspNetCore.Diagnostics.Identity.Service
|
|||
|
||||
public async Task InvokeAsync(HttpContext context)
|
||||
{
|
||||
var credentialsProvider = context.RequestServices.GetRequiredService<ISigningCredentialsPolicyProvider>();
|
||||
var openIdOptionsCache = context.RequestServices.GetRequiredService<IOptionsCache<OpenIdConnectOptions>>();
|
||||
|
||||
var credentialsProvider = context.RequestServices.GetService<DeveloperCertificateSigningCredentialsSource>();
|
||||
if (credentialsProvider == null)
|
||||
{
|
||||
await _next(context);
|
||||
return;
|
||||
}
|
||||
var openIdOptionsCache = context.RequestServices.GetRequiredService<IOptionsCache<OpenIdConnectOptions>>();
|
||||
if (_environment.IsDevelopment() &&
|
||||
context.Request.Path.Equals(_options.Value.ListeningEndpoint))
|
||||
{
|
||||
if (context.Request.Method.Equals(HttpMethods.Get))
|
||||
{
|
||||
var credentials = await credentialsProvider.GetAllCredentialsAsync();
|
||||
var credentials = await credentialsProvider.GetCredentials();
|
||||
bool hasDevelopmentCertificate = await IsDevelopmentCertificateConfiguredAndValid();
|
||||
var foundDeveloperCertificate = FoundDeveloperCertificate();
|
||||
if (!foundDeveloperCertificate || !hasDevelopmentCertificate)
|
||||
|
|
@ -102,7 +107,6 @@ namespace Microsoft.AspNetCore.Diagnostics.Identity.Service
|
|||
store.Open(OpenFlags.ReadWrite);
|
||||
store.Add(imported);
|
||||
store.Close();
|
||||
_identityServiceOptionsCache.TryRemove(Options.DefaultName);
|
||||
openIdOptionsCache.TryRemove(OpenIdConnectDefaults.AuthenticationScheme);
|
||||
|
||||
context.Response.StatusCode = StatusCodes.Status204NoContent;
|
||||
|
|
@ -131,7 +135,7 @@ namespace Microsoft.AspNetCore.Diagnostics.Identity.Service
|
|||
|
||||
async Task<bool> IsDevelopmentCertificateConfiguredAndValid()
|
||||
{
|
||||
var certificates = await credentialsProvider.GetAllCredentialsAsync();
|
||||
var certificates = await credentialsProvider.GetCredentials();
|
||||
return certificates.Any(
|
||||
c => _timeStampManager.IsValidPeriod(c.NotBefore, c.Expires) &&
|
||||
c.Credentials.Key is X509SecurityKey key &&
|
||||
|
|
|
|||
|
|
@ -0,0 +1,73 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
|
||||
namespace Microsoft.AspNetCore.Identity.Service
|
||||
{
|
||||
public class DeveloperCertificateSigningCredentialsSource : ISigningCredentialsSource
|
||||
{
|
||||
private readonly IHostingEnvironment _environment;
|
||||
private readonly ITimeStampManager _timeStampManager;
|
||||
|
||||
public DeveloperCertificateSigningCredentialsSource(
|
||||
IHostingEnvironment environment,
|
||||
ITimeStampManager timeStampManager)
|
||||
{
|
||||
_environment = environment;
|
||||
_timeStampManager = timeStampManager;
|
||||
}
|
||||
|
||||
public Task<IEnumerable<SigningCredentialsDescriptor>> GetCredentials()
|
||||
{
|
||||
if (!_environment.IsDevelopment())
|
||||
{
|
||||
return Task.FromResult(Enumerable.Empty<SigningCredentialsDescriptor>());
|
||||
}
|
||||
|
||||
using (var store = new X509Store(StoreName.My, StoreLocation.CurrentUser))
|
||||
{
|
||||
store.Open(OpenFlags.ReadOnly);
|
||||
var cert = store.Certificates.Find(X509FindType.FindBySubjectDistinguishedName, "CN=IdentityService.Development", validOnly: false);
|
||||
var valid = cert.OfType<X509Certificate2>().FirstOrDefault(c => _timeStampManager.IsValidPeriod(c.NotBefore, c.NotAfter));
|
||||
store.Close();
|
||||
|
||||
if (valid != null)
|
||||
{
|
||||
return Task.FromResult<IEnumerable<SigningCredentialsDescriptor>>(new[] { CreateDescriptor(valid) });
|
||||
}
|
||||
else
|
||||
{
|
||||
return Task.FromResult(Enumerable.Empty<SigningCredentialsDescriptor>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private SigningCredentialsDescriptor CreateDescriptor(X509Certificate2 certificate)
|
||||
{
|
||||
CryptographyHelpers.ValidateRsaKeyLength(certificate);
|
||||
var credentials = new SigningCredentials(new X509SecurityKey(certificate), CryptographyHelpers.FindAlgorithm(certificate));
|
||||
return new SigningCredentialsDescriptor(
|
||||
credentials,
|
||||
CryptographyHelpers.GetAlgorithm(credentials),
|
||||
certificate.NotBefore,
|
||||
certificate.NotAfter,
|
||||
GetMetadata());
|
||||
|
||||
IDictionary<string, string> GetMetadata()
|
||||
{
|
||||
var rsaParameters = CryptographyHelpers.GetRSAParameters(credentials);
|
||||
return new Dictionary<string, string>
|
||||
{
|
||||
[JsonWebKeyParameterNames.E] = Base64UrlEncoder.Encode(rsaParameters.Exponent),
|
||||
[JsonWebKeyParameterNames.N] = Base64UrlEncoder.Encode(rsaParameters.Modulus),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,7 +3,9 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using Microsoft.AspNetCore.Identity.Service.Core;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
|
||||
|
|
@ -56,6 +58,20 @@ namespace Microsoft.AspNetCore.Identity.Service
|
|||
return builder;
|
||||
}
|
||||
|
||||
public static IIdentityServiceBuilder DisableDeveloperCertificate(this IIdentityServiceBuilder builder)
|
||||
{
|
||||
var services = builder.Services;
|
||||
foreach (var service in services.ToList())
|
||||
{
|
||||
if (service.ImplementationType == typeof(DeveloperCertificateSigningCredentialsSource))
|
||||
{
|
||||
services.Remove(service);
|
||||
}
|
||||
}
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static IIdentityServiceBuilder AddSigningCertificate(this IIdentityServiceBuilder builder, Func<X509Certificate2> func)
|
||||
{
|
||||
var cert = func();
|
||||
|
|
|
|||
|
|
@ -83,6 +83,8 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
services.AddSingleton<ITokenClaimsProvider, TimestampsTokenClaimsProvider>();
|
||||
services.AddSingleton<ITokenClaimsProvider, TokenHashTokenClaimsProvider>();
|
||||
services.AddSingleton<ProtocolErrorProvider>();
|
||||
services.AddSingleton<ISigningCredentialsSource, DeveloperCertificateSigningCredentialsSource>();
|
||||
services.AddSingleton<DeveloperCertificateSigningCredentialsSource>();
|
||||
|
||||
services.AddSingleton<IPasswordHasher<TApplication>, PasswordHasher<TApplication>>();
|
||||
services.AddScoped<ISigningCredentialsPolicyProvider, DefaultSigningCredentialsPolicyProvider>();
|
||||
|
|
|
|||
Loading…
Reference in New Issue