-
Notifications
You must be signed in to change notification settings - Fork 10.4k
Add CertificateAuthentication #9756
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 40 commits
Commits
Show all changes
54 commits
Select commit
Hold shift + click to select a range
a2ea84d
Initial snapshot of CertAuth (tests pass)
HaoK 609c678
Fix sample remove commented tests
HaoK 4ac7474
Use built in GetCertHashString
HaoK df15031
Update Microsoft.AspNetCore.Authentication.Certificate.netcoreapp3.0.cs
HaoK 245c478
Skip failing self signing cert tests on linux
HaoK ec39624
Initial snapshot of CertAuth (tests pass)
HaoK 242616d
Stuff
HaoK 60762fb
Use right header
HaoK 83a9560
Move CertForwarderMiddleware to HttpOverrides
HaoK 9c006c8
Collapse null checks
HaoK ed02704
Delete Cert validator
HaoK 95508f0
remove no warn
HaoK da2dc36
Update src/Middleware/HttpOverrides/src/CertificateForwarderExtension…
HaoK 8ead62b
Update src/Middleware/HttpOverrides/src/CertificateForwarderExtension…
HaoK d079170
Add doc comments
HaoK 758d1af
Update src/Middleware/HttpOverrides/src/CertificateForwarderOptions.cs
HaoK b222348
Update src/Middleware/HttpOverrides/src/CertificateForwarderOptions.cs
HaoK 6806957
Update src/Security/Authentication/Certificate/samples/Certificate.Sa…
HaoK e3bb3d0
Update src/Security/Authentication/Certificate/samples/Certificate.Sa…
HaoK 1f7e8a6
Update src/Security/Authentication/Certificate/samples/Certificate.Sa…
HaoK 8650102
Update src/Security/Authentication/Certificate/samples/Certificate.Sa…
HaoK c57c2fc
Update src/Security/Authentication/Certificate/samples/Certificate.Sa…
HaoK 44b87eb
Update MessagePack-CSharp
HaoK 23b8d88
Update self signed certs to CertSign key usage
HaoK 460ede1
Add some tests for CertificateForwarderMiddleware
HaoK 07e9971
Doc comments galore, add tests, PR feedback
HaoK a616c13
Update Microsoft.AspNetCore.Authentication.Certificate.csproj
HaoK 93afcbd
Update SharedFramework.Local.props
HaoK 254606d
Fix sample
HaoK 1893a9c
Update Program.cs
HaoK 3e8b045
Update Program.cs
HaoK 1dde847
Update CertificateAuthenticationHandler.cs
HaoK 5b92b6f
Update CertificateTypes.cs
HaoK 10b5eda
Fix typo
HaoK 91c1663
Update Microsoft.AspNetCore.Authentication.Certificate.netcoreapp3.0.cs
HaoK d6e41eb
Add TlsConnectionFeature for cert forward header
HaoK 33ac70d
Switch to span sequence equals
HaoK b6febd2
Add structured logging
HaoK f0f66f8
Fix sample
HaoK a957b88
PR feedback
HaoK 18f9296
Switch default header to X-Client-Cert for forwarder
HaoK 908fb39
Create principal earlier for event
HaoK 6943636
Code review feedback
HaoK 8b3a435
Update src/Security/Authentication/Certificate/src/Microsoft.AspNetCo…
HaoK 0eaa6fb
Add logging
HaoK a20c0c1
Merge branch 'security-cert' of https://github.com/aspnet/AspNetCore …
HaoK c592bc5
Feedback updates
HaoK 22350cf
Fix tests
HaoK 633edb2
Fix refs
HaoK 3c8f335
Update src/Security/Authentication/Certificate/src/CertificateAuthent…
HaoK cae80fd
Renames
HaoK 3d8510b
Update Microsoft.AspNetCore.HttpOverrides.netcoreapp3.0.cs
HaoK 5e64221
Update Microsoft.AspNetCore.Authentication.Certificate.netcoreapp3.0.cs
HaoK 7235295
Update Microsoft.AspNetCore.HttpOverrides.netcoreapp3.0.cs
HaoK File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
55 changes: 55 additions & 0 deletions
55
src/Middleware/HttpOverrides/src/CertificateForwarderExtensions.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
// 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; | ||
using Microsoft.AspNetCore.HttpOverrides; | ||
using Microsoft.Extensions.DependencyInjection; | ||
|
||
namespace Microsoft.AspNetCore.Builder | ||
{ | ||
/// <summary> | ||
/// Extension methods for using the certificate fowarder. | ||
/// </summary> | ||
public static class CertificateForwarderExtensions | ||
HaoK marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{ | ||
/// <summary> | ||
/// Adds a middleware to the pipeline that will look for a certificate in a request header | ||
/// decode it, and updates HttpContext.Connection.ClientCertificate. | ||
/// </summary> | ||
/// <param name="app"></param> | ||
/// <returns></returns> | ||
public static IApplicationBuilder UseCertificateHeaderForwarding(this IApplicationBuilder app) | ||
{ | ||
if (app == null) | ||
{ | ||
throw new ArgumentNullException(nameof(app)); | ||
} | ||
|
||
return app.UseMiddleware<CertificateForwarderMiddleware>(); | ||
} | ||
|
||
/// <summary> | ||
/// Adds certificate forwarding to the specified <see cref="IServiceCollection" />. | ||
/// </summary> | ||
/// <param name="services">The <see cref="IServiceCollection"/>.</param> | ||
/// <param name="configure">An action delegate to configure the provided <see cref="CertificateForwarderOptions"/>.</param> | ||
/// <returns>The <see cref="IServiceCollection"/> so that additional calls can be chained.</returns> | ||
public static IServiceCollection AddCertificateHeaderForwarding( | ||
this IServiceCollection services, | ||
Action<CertificateForwarderOptions> configure) | ||
{ | ||
if (services == null) | ||
{ | ||
throw new ArgumentNullException(nameof(services)); | ||
} | ||
|
||
if (configure == null) | ||
{ | ||
throw new ArgumentNullException(nameof(configure)); | ||
} | ||
|
||
services.AddOptions<CertificateForwarderOptions>().Validate(o => !string.IsNullOrEmpty(o.CertificateHeader), "CertificateForwarderOptions.CertificateHeader cannot be null or empty."); | ||
return services.Configure(configure); | ||
} | ||
} | ||
} |
51 changes: 51 additions & 0 deletions
51
src/Middleware/HttpOverrides/src/CertificateForwarderFeature.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
// 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; | ||
using System.Security.Cryptography.X509Certificates; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using Microsoft.AspNetCore.Http.Features; | ||
using Microsoft.Extensions.Logging; | ||
using Microsoft.Extensions.Primitives; | ||
|
||
namespace Microsoft.AspNetCore.HttpOverrides | ||
{ | ||
internal class CertificateForwarderFeature : ITlsConnectionFeature | ||
{ | ||
private ILogger _logger; | ||
private StringValues _header; | ||
private CertificateForwarderOptions _options; | ||
private X509Certificate2 _certificate; | ||
|
||
public CertificateForwarderFeature(ILogger logger, StringValues header, CertificateForwarderOptions options) | ||
{ | ||
_logger = logger; | ||
_options = options; | ||
_header = header; | ||
} | ||
|
||
public X509Certificate2 ClientCertificate | ||
{ | ||
get | ||
{ | ||
if (_certificate == null && _header != StringValues.Empty) | ||
{ | ||
try | ||
{ | ||
_certificate = _options.HeaderConverter(_header); | ||
} | ||
catch (Exception e) | ||
{ | ||
_logger.LogWarning(0, e, "Could not read certificate from header."); | ||
HaoK marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
} | ||
return _certificate; | ||
} | ||
set => _certificate = value; | ||
} | ||
|
||
public Task<X509Certificate2> GetClientCertificateAsync(CancellationToken cancellationToken) | ||
=> Task.FromResult(ClientCertificate); | ||
} | ||
} |
70 changes: 70 additions & 0 deletions
70
src/Middleware/HttpOverrides/src/CertificateForwarderMiddleware.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
// 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; | ||
using System.Threading.Tasks; | ||
using Microsoft.AspNetCore.Http; | ||
using Microsoft.AspNetCore.Http.Features; | ||
using Microsoft.Extensions.Logging; | ||
using Microsoft.Extensions.Options; | ||
using Microsoft.Extensions.Primitives; | ||
|
||
namespace Microsoft.AspNetCore.HttpOverrides | ||
{ | ||
/// <summary> | ||
/// Middleware that converts a forward header into a client certificate if found. | ||
/// </summary> | ||
public class CertificateForwarderMiddleware | ||
HaoK marked this conversation as resolved.
Show resolved
Hide resolved
Tratcher marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{ | ||
private readonly RequestDelegate _next; | ||
private readonly CertificateForwarderOptions _options; | ||
private readonly ILogger _logger; | ||
|
||
/// <summary> | ||
/// Constructor. | ||
/// </summary> | ||
/// <param name="next"></param> | ||
/// <param name="loggerFactory"></param> | ||
/// <param name="options"></param> | ||
public CertificateForwarderMiddleware( | ||
RequestDelegate next, | ||
ILoggerFactory loggerFactory, | ||
IOptions<CertificateForwarderOptions> options) | ||
{ | ||
_next = next ?? throw new ArgumentNullException(nameof(next)); | ||
|
||
if (loggerFactory == null) | ||
{ | ||
throw new ArgumentNullException(nameof(loggerFactory)); | ||
} | ||
|
||
if (options == null) | ||
{ | ||
throw new ArgumentNullException(nameof(options)); | ||
} | ||
|
||
_options = options.Value; | ||
_logger = loggerFactory.CreateLogger<CertificateForwarderMiddleware>(); | ||
} | ||
|
||
/// <summary> | ||
/// Looks for the presence of a <see cref="CertificateForwarderOptions.CertificateHeader"/> header in the request, | ||
/// if found, converts this header to a ClientCertificate set on the connection. | ||
/// </summary> | ||
/// <param name="httpContext">The <see cref="HttpContext"/>.</param> | ||
/// <returns>A <see cref="Task"/>.</returns> | ||
public async Task Invoke(HttpContext httpContext) | ||
{ | ||
var clientCertificate = await httpContext.Connection.GetClientCertificateAsync(); | ||
HaoK marked this conversation as resolved.
Show resolved
Hide resolved
HaoK marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if (clientCertificate == null) | ||
{ | ||
var header = httpContext.Request.Headers[_options.CertificateHeader]; | ||
if (!StringValues.IsNullOrEmpty(header)) | ||
{ | ||
httpContext.Features.Set<ITlsConnectionFeature>(new CertificateForwarderFeature(_logger, header, _options)); | ||
} | ||
} | ||
await _next(httpContext); | ||
} | ||
} | ||
} |
30 changes: 30 additions & 0 deletions
30
src/Middleware/HttpOverrides/src/CertificateForwarderOptions.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
// 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; | ||
using System.Security.Cryptography.X509Certificates; | ||
|
||
namespace Microsoft.AspNetCore.HttpOverrides | ||
{ | ||
/// <summary> | ||
/// Used to configure the <see cref="CertificateForwarderMiddleware"/>. | ||
/// </summary> | ||
public class CertificateForwarderOptions | ||
{ | ||
/// <summary> | ||
/// The name of the header containing the client certificate. | ||
/// </summary> | ||
/// <remarks> | ||
/// This defaults to X-ARR-ClientCert, which is the header Azure Web Apps uses. | ||
/// </remarks> | ||
public string CertificateHeader { get; set; } = "X-ARR-ClientCert"; | ||
HaoK marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
/// <summary> | ||
/// The function used to convert the header to an instance of <see cref="X509Certificate2"/>. | ||
/// </summary> | ||
/// <remarks> | ||
/// This defaults to a conversion from a base64 encoded string. | ||
/// </remarks> | ||
public Func<string, X509Certificate2> HeaderConverter = (headerValue) => new X509Certificate2(Convert.FromBase64String(headerValue)); | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.