629 lines
26 KiB
C#
629 lines
26 KiB
C#
// Copyright (c) Barry Dorrans. All rights reserved.
|
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
|
|
|
using System;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Net;
|
|
using System.Security.Claims;
|
|
using System.Security.Cryptography.X509Certificates;
|
|
using System.Threading.Tasks;
|
|
using System.Xml.Linq;
|
|
using Microsoft.AspNetCore.Builder;
|
|
using Microsoft.AspNetCore.Hosting;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.AspNetCore.TestHost;
|
|
using Microsoft.AspNetCore.Testing.xunit;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Xunit;
|
|
|
|
namespace Microsoft.AspNetCore.Authentication.Certificate.Test
|
|
{
|
|
public class ClientCertificateAuthenticationTests
|
|
{
|
|
|
|
[Fact]
|
|
public async Task VerifySchemeDefaults()
|
|
{
|
|
var services = new ServiceCollection();
|
|
services.AddAuthentication().AddCertificate();
|
|
var sp = services.BuildServiceProvider();
|
|
var schemeProvider = sp.GetRequiredService<IAuthenticationSchemeProvider>();
|
|
var scheme = await schemeProvider.GetSchemeAsync(CertificateAuthenticationDefaults.AuthenticationScheme);
|
|
Assert.NotNull(scheme);
|
|
Assert.Equal("CertificateAuthenticationHandler", scheme.HandlerType.Name);
|
|
Assert.Null(scheme.DisplayName);
|
|
}
|
|
|
|
[Fact]
|
|
public void VerifyIsSelfSignedExtensionMethod()
|
|
{
|
|
Assert.True(Certificates.SelfSignedValidWithNoEku.IsSelfSigned());
|
|
}
|
|
|
|
[Fact]
|
|
public async Task VerifyValidSelfSignedWithClientEkuAuthenticates()
|
|
{
|
|
var server = CreateServer(
|
|
new CertificateAuthenticationOptions
|
|
{
|
|
AllowedCertificateTypes = CertificateTypes.SelfSigned,
|
|
Events = sucessfulValidationEvents
|
|
},
|
|
Certificates.SelfSignedValidWithClientEku);
|
|
|
|
var response = await server.CreateClient().GetAsync("https://example.com/");
|
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task VerifyValidSelfSignedWithNoEkuAuthenticates()
|
|
{
|
|
var server = CreateServer(
|
|
new CertificateAuthenticationOptions
|
|
{
|
|
AllowedCertificateTypes = CertificateTypes.SelfSigned,
|
|
Events = sucessfulValidationEvents
|
|
},
|
|
Certificates.SelfSignedValidWithNoEku);
|
|
|
|
var response = await server.CreateClient().GetAsync("https://example.com/");
|
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task VerifyValidSelfSignedWithClientEkuFailsWhenSelfSignedCertsNotAllowed()
|
|
{
|
|
var server = CreateServer(
|
|
new CertificateAuthenticationOptions
|
|
{
|
|
AllowedCertificateTypes = CertificateTypes.Chained
|
|
},
|
|
Certificates.SelfSignedValidWithClientEku);
|
|
|
|
var response = await server.CreateClient().GetAsync("https://example.com/");
|
|
Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task VerifyValidSelfSignedWithNoEkuFailsWhenSelfSignedCertsNotAllowed()
|
|
{
|
|
var server = CreateServer(
|
|
new CertificateAuthenticationOptions
|
|
{
|
|
AllowedCertificateTypes = CertificateTypes.Chained,
|
|
Events = sucessfulValidationEvents
|
|
},
|
|
Certificates.SelfSignedValidWithNoEku);
|
|
|
|
var response = await server.CreateClient().GetAsync("https://example.com/");
|
|
Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task VerifyValidSelfSignedWithServerFailsEvenIfSelfSignedCertsAreAllowed()
|
|
{
|
|
var server = CreateServer(
|
|
new CertificateAuthenticationOptions
|
|
{
|
|
AllowedCertificateTypes = CertificateTypes.SelfSigned,
|
|
Events = sucessfulValidationEvents
|
|
},
|
|
Certificates.SelfSignedValidWithServerEku);
|
|
|
|
var response = await server.CreateClient().GetAsync("https://example.com/");
|
|
Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task VerifyValidSelfSignedWithServerPassesWhenSelfSignedCertsAreAllowedAndPurposeValidationIsOff()
|
|
{
|
|
var server = CreateServer(
|
|
new CertificateAuthenticationOptions
|
|
{
|
|
AllowedCertificateTypes = CertificateTypes.SelfSigned,
|
|
ValidateCertificateUse = false,
|
|
Events = sucessfulValidationEvents
|
|
},
|
|
Certificates.SelfSignedValidWithServerEku);
|
|
|
|
var response = await server.CreateClient().GetAsync("https://example.com/");
|
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task VerifyValidSelfSignedWithServerFailsPurposeValidationIsOffButSelfSignedCertsAreNotAllowed()
|
|
{
|
|
var server = CreateServer(
|
|
new CertificateAuthenticationOptions
|
|
{
|
|
AllowedCertificateTypes = CertificateTypes.Chained,
|
|
ValidateCertificateUse = false,
|
|
Events = sucessfulValidationEvents
|
|
},
|
|
Certificates.SelfSignedValidWithServerEku);
|
|
|
|
var response = await server.CreateClient().GetAsync("https://example.com/");
|
|
Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task VerifyExpiredSelfSignedFails()
|
|
{
|
|
var server = CreateServer(
|
|
new CertificateAuthenticationOptions
|
|
{
|
|
AllowedCertificateTypes = CertificateTypes.SelfSigned,
|
|
ValidateCertificateUse = false,
|
|
Events = sucessfulValidationEvents
|
|
},
|
|
Certificates.SelfSignedExpired);
|
|
|
|
var response = await server.CreateClient().GetAsync("https://example.com/");
|
|
Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task VerifyExpiredSelfSignedPassesIfDateRangeValidationIsDisabled()
|
|
{
|
|
var server = CreateServer(
|
|
new CertificateAuthenticationOptions
|
|
{
|
|
AllowedCertificateTypes = CertificateTypes.SelfSigned,
|
|
ValidateValidityPeriod = false,
|
|
Events = sucessfulValidationEvents
|
|
},
|
|
Certificates.SelfSignedExpired);
|
|
|
|
var response = await server.CreateClient().GetAsync("https://example.com/");
|
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task VerifyNotYetValidSelfSignedFails()
|
|
{
|
|
var server = CreateServer(
|
|
new CertificateAuthenticationOptions
|
|
{
|
|
AllowedCertificateTypes = CertificateTypes.SelfSigned,
|
|
ValidateCertificateUse = false,
|
|
Events = sucessfulValidationEvents
|
|
},
|
|
Certificates.SelfSignedNotYetValid);
|
|
|
|
var response = await server.CreateClient().GetAsync("https://example.com/");
|
|
Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task VerifyNotYetValidSelfSignedPassesIfDateRangeValidationIsDisabled()
|
|
{
|
|
var server = CreateServer(
|
|
new CertificateAuthenticationOptions
|
|
{
|
|
AllowedCertificateTypes = CertificateTypes.SelfSigned,
|
|
ValidateValidityPeriod = false,
|
|
Events = sucessfulValidationEvents
|
|
},
|
|
Certificates.SelfSignedNotYetValid);
|
|
|
|
var response = await server.CreateClient().GetAsync("https://example.com/");
|
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task VerifyFailingInTheValidationEventReturnsForbidden()
|
|
{
|
|
var server = CreateServer(
|
|
new CertificateAuthenticationOptions
|
|
{
|
|
ValidateCertificateUse = false,
|
|
Events = failedValidationEvents
|
|
},
|
|
Certificates.SelfSignedValidWithServerEku);
|
|
|
|
var response = await server.CreateClient().GetAsync("https://example.com/");
|
|
Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task DoingNothingInTheValidationEventReturnsOK()
|
|
{
|
|
var server = CreateServer(
|
|
new CertificateAuthenticationOptions
|
|
{
|
|
AllowedCertificateTypes = CertificateTypes.SelfSigned,
|
|
ValidateCertificateUse = false,
|
|
Events = unprocessedValidationEvents
|
|
},
|
|
Certificates.SelfSignedValidWithServerEku);
|
|
|
|
var response = await server.CreateClient().GetAsync("https://example.com/");
|
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task VerifyNotSendingACertificateEndsUpInForbidden()
|
|
{
|
|
var server = CreateServer(
|
|
new CertificateAuthenticationOptions
|
|
{
|
|
Events = sucessfulValidationEvents
|
|
});
|
|
|
|
var response = await server.CreateClient().GetAsync("https://example.com/");
|
|
Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task VerifyHeaderIsUsedIfCertIsNotPresent()
|
|
{
|
|
var server = CreateServer(
|
|
new CertificateAuthenticationOptions
|
|
{
|
|
AllowedCertificateTypes = CertificateTypes.SelfSigned,
|
|
Events = sucessfulValidationEvents
|
|
},
|
|
wireUpHeaderMiddleware : true);
|
|
|
|
var client = server.CreateClient();
|
|
client.DefaultRequestHeaders.Add("X-Client-Cert", Convert.ToBase64String(Certificates.SelfSignedValidWithNoEku.RawData));
|
|
var response = await client.GetAsync("https://example.com/");
|
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task VerifyHeaderEncodedCertFailsOnBadEncoding()
|
|
{
|
|
var server = CreateServer(
|
|
new CertificateAuthenticationOptions
|
|
{
|
|
Events = sucessfulValidationEvents
|
|
},
|
|
wireUpHeaderMiddleware: true);
|
|
|
|
var client = server.CreateClient();
|
|
client.DefaultRequestHeaders.Add("X-Client-Cert", "OOPS" + Convert.ToBase64String(Certificates.SelfSignedValidWithNoEku.RawData));
|
|
var response = await client.GetAsync("https://example.com/");
|
|
Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task VerifySettingTheAzureHeaderOnTheForwarderOptionsWorks()
|
|
{
|
|
var server = CreateServer(
|
|
new CertificateAuthenticationOptions
|
|
{
|
|
AllowedCertificateTypes = CertificateTypes.SelfSigned,
|
|
Events = sucessfulValidationEvents
|
|
},
|
|
wireUpHeaderMiddleware: true,
|
|
headerName: "X-ARR-ClientCert");
|
|
|
|
var client = server.CreateClient();
|
|
client.DefaultRequestHeaders.Add("X-ARR-ClientCert", Convert.ToBase64String(Certificates.SelfSignedValidWithNoEku.RawData));
|
|
var response = await client.GetAsync("https://example.com/");
|
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task VerifyACustomHeaderFailsIfTheHeaderIsNotPresent()
|
|
{
|
|
var server = CreateServer(
|
|
new CertificateAuthenticationOptions
|
|
{
|
|
Events = sucessfulValidationEvents
|
|
},
|
|
wireUpHeaderMiddleware: true,
|
|
headerName: "X-ARR-ClientCert");
|
|
|
|
var client = server.CreateClient();
|
|
client.DefaultRequestHeaders.Add("random-Weird-header", Convert.ToBase64String(Certificates.SelfSignedValidWithNoEku.RawData));
|
|
var response = await client.GetAsync("https://example.com/");
|
|
Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task VerifyNoEventWireupWithAValidCertificateCreatesADefaultUser()
|
|
{
|
|
var server = CreateServer(
|
|
new CertificateAuthenticationOptions
|
|
{
|
|
AllowedCertificateTypes = CertificateTypes.SelfSigned
|
|
},
|
|
Certificates.SelfSignedValidWithNoEku);
|
|
|
|
var response = await server.CreateClient().GetAsync("https://example.com/");
|
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
|
|
|
XElement responseAsXml = null;
|
|
if (response.Content != null &&
|
|
response.Content.Headers.ContentType != null &&
|
|
response.Content.Headers.ContentType.MediaType == "text/xml")
|
|
{
|
|
var responseContent = await response.Content.ReadAsStringAsync();
|
|
responseAsXml = XElement.Parse(responseContent);
|
|
}
|
|
|
|
Assert.NotNull(responseAsXml);
|
|
|
|
// There should always be an Issuer and a Thumbprint.
|
|
var actual = responseAsXml.Elements("claim").Where(claim => claim.Attribute("Type").Value == "issuer");
|
|
Assert.Single(actual);
|
|
Assert.Equal(Certificates.SelfSignedValidWithNoEku.Issuer, actual.First().Value);
|
|
|
|
actual = responseAsXml.Elements("claim").Where(claim => claim.Attribute("Type").Value == ClaimTypes.Thumbprint);
|
|
Assert.Single(actual);
|
|
Assert.Equal(Certificates.SelfSignedValidWithNoEku.Thumbprint, actual.First().Value);
|
|
|
|
// Now the optional ones
|
|
if (!string.IsNullOrEmpty(Certificates.SelfSignedValidWithNoEku.SubjectName.Name))
|
|
{
|
|
actual = responseAsXml.Elements("claim").Where(claim => claim.Attribute("Type").Value == ClaimTypes.X500DistinguishedName);
|
|
if (actual.Count() > 0)
|
|
{
|
|
Assert.Single(actual);
|
|
Assert.Equal(Certificates.SelfSignedValidWithNoEku.SubjectName.Name, actual.First().Value);
|
|
}
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(Certificates.SelfSignedValidWithNoEku.SerialNumber))
|
|
{
|
|
actual = responseAsXml.Elements("claim").Where(claim => claim.Attribute("Type").Value == ClaimTypes.SerialNumber);
|
|
if (actual.Count() > 0)
|
|
{
|
|
Assert.Single(actual);
|
|
Assert.Equal(Certificates.SelfSignedValidWithNoEku.SerialNumber, actual.First().Value);
|
|
}
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(Certificates.SelfSignedValidWithNoEku.GetNameInfo(X509NameType.DnsName, false)))
|
|
{
|
|
actual = responseAsXml.Elements("claim").Where(claim => claim.Attribute("Type").Value == ClaimTypes.Dns);
|
|
if (actual.Count() > 0)
|
|
{
|
|
Assert.Single(actual);
|
|
Assert.Equal(Certificates.SelfSignedValidWithNoEku.GetNameInfo(X509NameType.DnsName, false), actual.First().Value);
|
|
}
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(Certificates.SelfSignedValidWithNoEku.GetNameInfo(X509NameType.EmailName, false)))
|
|
{
|
|
actual = responseAsXml.Elements("claim").Where(claim => claim.Attribute("Type").Value == ClaimTypes.Email);
|
|
if (actual.Count() > 0)
|
|
{
|
|
Assert.Single(actual);
|
|
Assert.Equal(Certificates.SelfSignedValidWithNoEku.GetNameInfo(X509NameType.EmailName, false), actual.First().Value);
|
|
}
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(Certificates.SelfSignedValidWithNoEku.GetNameInfo(X509NameType.SimpleName, false)))
|
|
{
|
|
actual = responseAsXml.Elements("claim").Where(claim => claim.Attribute("Type").Value == ClaimTypes.Name);
|
|
if (actual.Count() > 0)
|
|
{
|
|
Assert.Single(actual);
|
|
Assert.Equal(Certificates.SelfSignedValidWithNoEku.GetNameInfo(X509NameType.SimpleName, false), actual.First().Value);
|
|
}
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(Certificates.SelfSignedValidWithNoEku.GetNameInfo(X509NameType.UpnName, false)))
|
|
{
|
|
actual = responseAsXml.Elements("claim").Where(claim => claim.Attribute("Type").Value == ClaimTypes.Upn);
|
|
if (actual.Count() > 0)
|
|
{
|
|
Assert.Single(actual);
|
|
Assert.Equal(Certificates.SelfSignedValidWithNoEku.GetNameInfo(X509NameType.UpnName, false), actual.First().Value);
|
|
}
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(Certificates.SelfSignedValidWithNoEku.GetNameInfo(X509NameType.UrlName, false)))
|
|
{
|
|
actual = responseAsXml.Elements("claim").Where(claim => claim.Attribute("Type").Value == ClaimTypes.Uri);
|
|
if (actual.Count() > 0)
|
|
{
|
|
Assert.Single(actual);
|
|
Assert.Equal(Certificates.SelfSignedValidWithNoEku.GetNameInfo(X509NameType.UrlName, false), actual.First().Value);
|
|
}
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public async Task VerifyValidationEventPrincipalIsPropogated()
|
|
{
|
|
const string Expected = "John Doe";
|
|
|
|
var server = CreateServer(
|
|
new CertificateAuthenticationOptions
|
|
{
|
|
AllowedCertificateTypes = CertificateTypes.SelfSigned,
|
|
Events = new CertificateAuthenticationEvents
|
|
{
|
|
OnCertificateValidated = context =>
|
|
{
|
|
// Make sure we get the validated principal
|
|
Assert.NotNull(context.Principal);
|
|
var claims = new[]
|
|
{
|
|
new Claim(ClaimTypes.Name, Expected, ClaimValueTypes.String, context.Options.ClaimsIssuer)
|
|
};
|
|
|
|
context.Principal = new ClaimsPrincipal(new ClaimsIdentity(claims, context.Scheme.Name));
|
|
context.Success();
|
|
return Task.CompletedTask;
|
|
}
|
|
}
|
|
},
|
|
Certificates.SelfSignedValidWithNoEku);
|
|
|
|
var response = await server.CreateClient().GetAsync("https://example.com/");
|
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
|
|
|
XElement responseAsXml = null;
|
|
if (response.Content != null &&
|
|
response.Content.Headers.ContentType != null &&
|
|
response.Content.Headers.ContentType.MediaType == "text/xml")
|
|
{
|
|
var responseContent = await response.Content.ReadAsStringAsync();
|
|
responseAsXml = XElement.Parse(responseContent);
|
|
}
|
|
|
|
Assert.NotNull(responseAsXml);
|
|
var actual = responseAsXml.Elements("claim").Where(claim => claim.Attribute("Type").Value == ClaimTypes.Name);
|
|
Assert.Single(actual);
|
|
Assert.Equal(Expected, actual.First().Value);
|
|
Assert.Single(responseAsXml.Elements("claim"));
|
|
}
|
|
|
|
private static TestServer CreateServer(
|
|
CertificateAuthenticationOptions configureOptions,
|
|
X509Certificate2 clientCertificate = null,
|
|
Func<HttpContext, bool> handler = null,
|
|
Uri baseAddress = null,
|
|
bool wireUpHeaderMiddleware = false,
|
|
string headerName = "")
|
|
{
|
|
var builder = new WebHostBuilder()
|
|
.Configure(app =>
|
|
{
|
|
app.Use((context, next) =>
|
|
{
|
|
if (clientCertificate != null)
|
|
{
|
|
context.Connection.ClientCertificate = clientCertificate;
|
|
}
|
|
return next();
|
|
});
|
|
|
|
|
|
if (wireUpHeaderMiddleware)
|
|
{
|
|
app.UseCertificateForwarding();
|
|
}
|
|
|
|
app.UseAuthentication();
|
|
|
|
app.Use(async (context, next) =>
|
|
{
|
|
var request = context.Request;
|
|
var response = context.Response;
|
|
|
|
var authenticationResult = await context.AuthenticateAsync();
|
|
|
|
if (authenticationResult.Succeeded)
|
|
{
|
|
response.StatusCode = (int)HttpStatusCode.OK;
|
|
response.ContentType = "text/xml";
|
|
|
|
await response.WriteAsync("<claims>");
|
|
foreach (Claim claim in context.User.Claims)
|
|
{
|
|
await response.WriteAsync($"<claim Type=\"{claim.Type}\" Issuer=\"{claim.Issuer}\">{claim.Value}</claim>");
|
|
}
|
|
await response.WriteAsync("</claims>");
|
|
}
|
|
else
|
|
{
|
|
await context.ChallengeAsync();
|
|
}
|
|
});
|
|
})
|
|
.ConfigureServices(services =>
|
|
{
|
|
if (configureOptions != null)
|
|
{
|
|
services.AddAuthentication(CertificateAuthenticationDefaults.AuthenticationScheme).AddCertificate(options =>
|
|
{
|
|
options.AllowedCertificateTypes = configureOptions.AllowedCertificateTypes;
|
|
options.Events = configureOptions.Events;
|
|
options.ValidateCertificateUse = configureOptions.ValidateCertificateUse;
|
|
options.RevocationFlag = options.RevocationFlag;
|
|
options.RevocationMode = options.RevocationMode;
|
|
options.ValidateValidityPeriod = configureOptions.ValidateValidityPeriod;
|
|
});
|
|
}
|
|
else
|
|
{
|
|
services.AddAuthentication(CertificateAuthenticationDefaults.AuthenticationScheme).AddCertificate();
|
|
}
|
|
|
|
if (wireUpHeaderMiddleware && !string.IsNullOrEmpty(headerName))
|
|
{
|
|
services.AddCertificateForwarding(options =>
|
|
{
|
|
options.CertificateHeader = headerName;
|
|
});
|
|
}
|
|
});
|
|
|
|
var server = new TestServer(builder)
|
|
{
|
|
BaseAddress = baseAddress
|
|
};
|
|
|
|
return server;
|
|
}
|
|
|
|
private CertificateAuthenticationEvents sucessfulValidationEvents = new CertificateAuthenticationEvents()
|
|
{
|
|
OnCertificateValidated = context =>
|
|
{
|
|
var claims = new[]
|
|
{
|
|
new Claim(ClaimTypes.NameIdentifier, context.ClientCertificate.Subject, ClaimValueTypes.String, context.Options.ClaimsIssuer),
|
|
new Claim(ClaimTypes.Name, context.ClientCertificate.Subject, ClaimValueTypes.String, context.Options.ClaimsIssuer)
|
|
};
|
|
|
|
context.Principal = new ClaimsPrincipal(new ClaimsIdentity(claims, context.Scheme.Name));
|
|
context.Success();
|
|
return Task.CompletedTask;
|
|
}
|
|
};
|
|
|
|
private CertificateAuthenticationEvents failedValidationEvents = new CertificateAuthenticationEvents()
|
|
{
|
|
OnCertificateValidated = context =>
|
|
{
|
|
context.Fail("Not validated");
|
|
return Task.CompletedTask;
|
|
}
|
|
};
|
|
|
|
private CertificateAuthenticationEvents unprocessedValidationEvents = new CertificateAuthenticationEvents()
|
|
{
|
|
OnCertificateValidated = context =>
|
|
{
|
|
return Task.CompletedTask;
|
|
}
|
|
};
|
|
|
|
private static class Certificates
|
|
{
|
|
public static X509Certificate2 SelfSignedValidWithClientEku { get; private set; } =
|
|
new X509Certificate2(GetFullyQualifiedFilePath("validSelfSignedClientEkuCertificate.cer"));
|
|
|
|
public static X509Certificate2 SelfSignedValidWithNoEku { get; private set; } =
|
|
new X509Certificate2(GetFullyQualifiedFilePath("validSelfSignedNoEkuCertificate.cer"));
|
|
|
|
public static X509Certificate2 SelfSignedValidWithServerEku { get; private set; } =
|
|
new X509Certificate2(GetFullyQualifiedFilePath("validSelfSignedServerEkuCertificate.cer"));
|
|
|
|
public static X509Certificate2 SelfSignedNotYetValid { get; private set; } =
|
|
new X509Certificate2(GetFullyQualifiedFilePath("selfSignedNoEkuCertificateNotValidYet.cer"));
|
|
|
|
public static X509Certificate2 SelfSignedExpired { get; private set; } =
|
|
new X509Certificate2(GetFullyQualifiedFilePath("selfSignedNoEkuCertificateExpired.cer"));
|
|
|
|
private static string GetFullyQualifiedFilePath(string filename)
|
|
{
|
|
var filePath = Path.Combine(AppContext.BaseDirectory, filename);
|
|
if (!File.Exists(filePath))
|
|
{
|
|
throw new FileNotFoundException(filePath);
|
|
}
|
|
return filePath;
|
|
}
|
|
}
|
|
}
|
|
}
|