diff --git a/src/Microsoft.AspNetCore.Authentication/ClaimsTransformationAppBuilderExtensions.cs b/src/Microsoft.AspNetCore.Authentication/ClaimsTransformationAppBuilderExtensions.cs index 1cc76b946e..1edb4a0f4b 100644 --- a/src/Microsoft.AspNetCore.Authentication/ClaimsTransformationAppBuilderExtensions.cs +++ b/src/Microsoft.AspNetCore.Authentication/ClaimsTransformationAppBuilderExtensions.cs @@ -35,7 +35,7 @@ namespace Microsoft.AspNetCore.Builder /// The to add the middleware to. /// A function that asynchronously transforms one to another. /// A reference to this instance after the operation has completed. - public static IApplicationBuilder UseClaimsTransformation(this IApplicationBuilder app, Func> transform) + public static IApplicationBuilder UseClaimsTransformation(this IApplicationBuilder app, Func> transform) { if (app == null) { @@ -46,12 +46,12 @@ namespace Microsoft.AspNetCore.Builder throw new ArgumentNullException(nameof(transform)); } - return app.UseClaimsTransformation(new ClaimsTransformationOptions + return app.UseClaimsTransformation(new ClaimsTransformationOptions { Transformer = new ClaimsTransformer { OnTransform = transform } }); } - + /// /// Adds the middleware to the specified , which enables claims transformation capabilities. /// diff --git a/src/Microsoft.AspNetCore.Authentication/ClaimsTransformationContext.cs b/src/Microsoft.AspNetCore.Authentication/ClaimsTransformationContext.cs new file mode 100644 index 0000000000..3c363ca98f --- /dev/null +++ b/src/Microsoft.AspNetCore.Authentication/ClaimsTransformationContext.cs @@ -0,0 +1,15 @@ +using Microsoft.AspNetCore.Http; +using System.Security.Claims; + +namespace Microsoft.AspNetCore.Authentication +{ + public class ClaimsTransformationContext + { + public ClaimsTransformationContext(HttpContext context) + { + Context = context; + } + public HttpContext Context { get; } + public ClaimsPrincipal Principal { get; set; } + } +} diff --git a/src/Microsoft.AspNetCore.Authentication/ClaimsTransformationHandler.cs b/src/Microsoft.AspNetCore.Authentication/ClaimsTransformationHandler.cs index 78d9a0845b..7a2c47e401 100644 --- a/src/Microsoft.AspNetCore.Authentication/ClaimsTransformationHandler.cs +++ b/src/Microsoft.AspNetCore.Authentication/ClaimsTransformationHandler.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Features.Authentication; namespace Microsoft.AspNetCore.Authentication @@ -12,10 +13,12 @@ namespace Microsoft.AspNetCore.Authentication public class ClaimsTransformationHandler : IAuthenticationHandler { private readonly IClaimsTransformer _transform; + private readonly HttpContext _httpContext; - public ClaimsTransformationHandler(IClaimsTransformer transform) + public ClaimsTransformationHandler(IClaimsTransformer transform, HttpContext httpContext) { _transform = transform; + _httpContext = httpContext; } public IAuthenticationHandler PriorHandler { get; set; } @@ -27,8 +30,12 @@ namespace Microsoft.AspNetCore.Authentication await PriorHandler.AuthenticateAsync(context); if (_transform != null && context?.Principal != null) { + var transformationContext = new ClaimsTransformationContext(_httpContext) + { + Principal = context.Principal + }; context.Authenticated( - await _transform.TransformAsync(context.Principal), + await _transform.TransformAsync(transformationContext), context.Properties, context.Description); } diff --git a/src/Microsoft.AspNetCore.Authentication/ClaimsTransformationMiddleware.cs b/src/Microsoft.AspNetCore.Authentication/ClaimsTransformationMiddleware.cs index 2e2216bc25..53f6a07a87 100644 --- a/src/Microsoft.AspNetCore.Authentication/ClaimsTransformationMiddleware.cs +++ b/src/Microsoft.AspNetCore.Authentication/ClaimsTransformationMiddleware.cs @@ -35,13 +35,17 @@ namespace Microsoft.AspNetCore.Authentication public async Task Invoke(HttpContext context) { - var handler = new ClaimsTransformationHandler(Options.Transformer); + var handler = new ClaimsTransformationHandler(Options.Transformer, context); handler.RegisterAuthenticationHandler(context.GetAuthentication()); try { if (Options.Transformer != null) { - context.User = await Options.Transformer.TransformAsync(context.User); + var transformationContext = new ClaimsTransformationContext(context) + { + Principal = context.User + }; + context.User = await Options.Transformer.TransformAsync(transformationContext); } await _next(context); } diff --git a/src/Microsoft.AspNetCore.Authentication/ClaimsTransformer.cs b/src/Microsoft.AspNetCore.Authentication/ClaimsTransformer.cs index b8e7ea3e1c..db05db0e5b 100644 --- a/src/Microsoft.AspNetCore.Authentication/ClaimsTransformer.cs +++ b/src/Microsoft.AspNetCore.Authentication/ClaimsTransformer.cs @@ -9,11 +9,11 @@ namespace Microsoft.AspNetCore.Authentication { public class ClaimsTransformer : IClaimsTransformer { - public Func> OnTransform { get; set; } + public Func> OnTransform { get; set; } - public virtual Task TransformAsync(ClaimsPrincipal principal) + public virtual Task TransformAsync(ClaimsTransformationContext context) { - return OnTransform?.Invoke(principal) ?? Task.FromResult(principal); + return OnTransform?.Invoke(context) ?? Task.FromResult(context.Principal); } } } diff --git a/src/Microsoft.AspNetCore.Authentication/IClaimsTransformer.cs b/src/Microsoft.AspNetCore.Authentication/IClaimsTransformer.cs index 5111c79714..cd42915c0a 100644 --- a/src/Microsoft.AspNetCore.Authentication/IClaimsTransformer.cs +++ b/src/Microsoft.AspNetCore.Authentication/IClaimsTransformer.cs @@ -14,8 +14,8 @@ namespace Microsoft.AspNetCore.Authentication /// /// Provides a central transformation point to change the specified principal. /// - /// The principal to transform. + /// containing principal to transform and current HttpContext. /// The transformed principal. - Task TransformAsync(ClaimsPrincipal principal); + Task TransformAsync(ClaimsTransformationContext context); } } diff --git a/test/Microsoft.AspNetCore.Authentication.Test/Cookies/CookieMiddlewareTests.cs b/test/Microsoft.AspNetCore.Authentication.Test/Cookies/CookieMiddlewareTests.cs index 785d5bfa62..5049f39e55 100644 --- a/test/Microsoft.AspNetCore.Authentication.Test/Cookies/CookieMiddlewareTests.cs +++ b/test/Microsoft.AspNetCore.Authentication.Test/Cookies/CookieMiddlewareTests.cs @@ -293,16 +293,16 @@ namespace Microsoft.AspNetCore.Authentication.Cookies { Transformer = new ClaimsTransformer { - OnTransform = p => + OnTransform = context => { - if (!p.Identities.Any(i => i.AuthenticationType == "xform")) + if (!context.Principal.Identities.Any(i => i.AuthenticationType == "xform")) { // REVIEW: Xform runs twice, once on Authenticate, and then once from the middleware var id = new ClaimsIdentity("xform"); id.AddClaim(new Claim("xform", "yup")); - p.AddIdentity(id); + context.Principal.AddIdentity(id); } - return Task.FromResult(p); + return Task.FromResult(context.Principal); } } }); diff --git a/test/Microsoft.AspNetCore.Authentication.Test/Google/GoogleMiddlewareTests.cs b/test/Microsoft.AspNetCore.Authentication.Test/Google/GoogleMiddlewareTests.cs index 96bb574fb3..31fb9e3175 100644 --- a/test/Microsoft.AspNetCore.Authentication.Test/Google/GoogleMiddlewareTests.cs +++ b/test/Microsoft.AspNetCore.Authentication.Test/Google/GoogleMiddlewareTests.cs @@ -222,7 +222,7 @@ namespace Microsoft.AspNetCore.Authentication.Google ClientId = "Test Id", ClientSecret = "Test Secret" }, - async context => + async context => { var req = context.Request; var res = context.Response; @@ -273,7 +273,7 @@ namespace Microsoft.AspNetCore.Authentication.Google { var transaction = await sendTask; Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode); - Assert.Equal("/error?FailureMessage=OMG"+UrlEncoder.Default.Encode(";Description=SoBad;Uri=foobar"), transaction.Response.Headers.GetValues("Location").First()); + Assert.Equal("/error?FailureMessage=OMG" + UrlEncoder.Default.Encode(";Description=SoBad;Uri=foobar"), transaction.Response.Headers.GetValues("Location").First()); } else { @@ -774,12 +774,12 @@ namespace Microsoft.AspNetCore.Authentication.Google AutomaticAuthenticate = true }); app.UseGoogleAuthentication(options); - app.UseClaimsTransformation(p => + app.UseClaimsTransformation(context => { var id = new ClaimsIdentity("xform"); id.AddClaim(new Claim("xform", "yup")); - p.AddIdentity(id); - return Task.FromResult(p); + context.Principal.AddIdentity(id); + return Task.FromResult(context.Principal); }); app.Use(async (context, next) => {