Skip to content
This repository was archived by the owner on Nov 1, 2018. It is now read-only.

Commit cc1cb1d

Browse files
committed
#27 Forward client certificates.
1 parent b2a3f87 commit cc1cb1d

File tree

5 files changed

+87
-1
lines changed

5 files changed

+87
-1
lines changed

samples/IISSample/Startup.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,15 @@ public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory)
2626
await context.Response.WriteAsync("User - " + context.User.Identity.Name + Environment.NewLine);
2727
await context.Response.WriteAsync("PathBase: " + context.Request.PathBase.Value + Environment.NewLine);
2828
await context.Response.WriteAsync("Path: " + context.Request.Path.Value + Environment.NewLine);
29+
await context.Response.WriteAsync("ClientCert: " + context.Connection.ClientCertificate + Environment.NewLine);
30+
31+
await context.Response.WriteAsync(Environment.NewLine + "Headers:" + Environment.NewLine);
2932
foreach (var header in context.Request.Headers)
3033
{
3134
await context.Response.WriteAsync(header.Key + ": " + header.Value + Environment.NewLine);
3235
}
36+
37+
await context.Response.WriteAsync(Environment.NewLine + "Environment Variables:" + Environment.NewLine);
3338
var vars = Environment.GetEnvironmentVariables();
3439
foreach (var key in vars.Keys)
3540
{
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Security.Cryptography.X509Certificates;
6+
using System.Threading;
7+
using System.Threading.Tasks;
8+
using Microsoft.AspNet.Http.Features;
9+
using Microsoft.Extensions.Logging;
10+
using Microsoft.Extensions.Primitives;
11+
12+
namespace Microsoft.AspNet.IISPlatformHandler
13+
{
14+
internal class ForwardedTlsConnectionFeature : ITlsConnectionFeature
15+
{
16+
private StringValues _header;
17+
private X509Certificate2 _certificate;
18+
private ILogger _logger;
19+
20+
public ForwardedTlsConnectionFeature(ILogger logger, StringValues header)
21+
{
22+
_logger = logger;
23+
_header = header;
24+
}
25+
26+
public X509Certificate2 ClientCertificate
27+
{
28+
get
29+
{
30+
if (_certificate == null && _header != StringValues.Empty)
31+
{
32+
try
33+
{
34+
var bytes = Convert.FromBase64String(_header);
35+
_certificate = new X509Certificate2(bytes);
36+
}
37+
catch (Exception ex)
38+
{
39+
_logger.LogWarning("Failed to read the client certificate.", ex);
40+
}
41+
}
42+
return _certificate;
43+
}
44+
set
45+
{
46+
_certificate = value;
47+
_header = StringValues.Empty;
48+
}
49+
}
50+
51+
public Task<X509Certificate2> GetClientCertificateAsync(CancellationToken cancellationToken)
52+
{
53+
return Task.FromResult(ClientCertificate);
54+
}
55+
}
56+
}

src/Microsoft.AspNet.IISPlatformHandler/IISPlatformHandlerMiddleware.cs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,16 @@
33

44
using System;
55
using System.Globalization;
6+
using System.Security.Cryptography.X509Certificates;
67
using System.Security.Principal;
78
using System.Threading.Tasks;
89
using Microsoft.AspNet.Builder;
910
using Microsoft.AspNet.Http;
11+
using Microsoft.AspNet.Http.Features;
1012
using Microsoft.AspNet.Http.Features.Authentication;
1113
using Microsoft.AspNet.Http.Features.Authentication.Internal;
1214
using Microsoft.Extensions.Internal;
15+
using Microsoft.Extensions.Logging;
1316
using Microsoft.Extensions.Options;
1417
using Microsoft.Extensions.Primitives;
1518

@@ -18,27 +21,43 @@ namespace Microsoft.AspNet.IISPlatformHandler
1821
public class IISPlatformHandlerMiddleware
1922
{
2023
private const string XIISWindowsAuthToken = "X-IIS-WindowsAuthToken";
24+
private const string MSPlatformHandlerClientCert = "MS-PLATFORM-HANDLER-CLIENTCERT";
2125

2226
private readonly RequestDelegate _next;
2327
private readonly IISPlatformHandlerOptions _options;
28+
private readonly ILogger _logger;
2429

25-
public IISPlatformHandlerMiddleware(RequestDelegate next, IOptions<IISPlatformHandlerOptions> options)
30+
public IISPlatformHandlerMiddleware(RequestDelegate next, ILoggerFactory loggerFactory, IOptions<IISPlatformHandlerOptions> options)
2631
{
2732
if (next == null)
2833
{
2934
throw new ArgumentNullException(nameof(next));
3035
}
36+
if (loggerFactory == null)
37+
{
38+
throw new ArgumentNullException(nameof(loggerFactory));
39+
}
3140
if (options == null)
3241
{
3342
throw new ArgumentNullException(nameof(options));
3443
}
3544

3645
_next = next;
3746
_options = options.Value;
47+
_logger = loggerFactory.CreateLogger<IISPlatformHandlerMiddleware>();
3848
}
3949

4050
public async Task Invoke(HttpContext httpContext)
4151
{
52+
if (_options.FlowClientCertificate)
53+
{
54+
var header = httpContext.Request.Headers[MSPlatformHandlerClientCert];
55+
if (!StringValues.IsNullOrEmpty(header))
56+
{
57+
httpContext.Features.Set<ITlsConnectionFeature>(new ForwardedTlsConnectionFeature(_logger, header));
58+
}
59+
}
60+
4261
if (_options.FlowWindowsAuthentication)
4362
{
4463
var winPrincipal = UpdateUser(httpContext);

src/Microsoft.AspNet.IISPlatformHandler/IISPlatformHandlerOptions.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ public class IISPlatformHandlerOptions
2222
/// </summary>
2323
public bool FlowWindowsAuthentication { get; set; } = true;
2424

25+
/// <summary>
26+
/// Populates the ITLSConnectionFeature if the MS-PLATFORM-HANDLER-CLIENTCERT request header is present.
27+
/// </summary>
28+
public bool FlowClientCertificate { get; set; } = true;
29+
2530
/// <summary>
2631
/// Additional information about the authentication type which is made available to the application.
2732
/// </summary>

src/Microsoft.AspNet.IISPlatformHandler/project.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"Microsoft.AspNet.Hosting.Abstractions": "1.0.0-*",
1414
"Microsoft.AspNet.Http": "1.0.0-*",
1515
"Microsoft.AspNet.Http.Extensions": "1.0.0-*",
16+
"Microsoft.Extensions.Logging.Abstractions": "1.0.0-*",
1617
"Microsoft.Extensions.Options": "1.0.0-*",
1718
"Microsoft.Extensions.SecurityHelper.Sources": {
1819
"type": "build",

0 commit comments

Comments
 (0)