IClaimsTransofrmer updated to take ClaimsTransformationContext instead of ClaimsPrincipal in TransformAsync method. #718

This commit is contained in:
Dovydas Navickas 2016-03-06 01:48:08 +02:00 committed by Hao Kung
parent 4bfeba2a3c
commit f5c1c45db2
8 changed files with 47 additions and 21 deletions

View File

@ -35,7 +35,7 @@ namespace Microsoft.AspNetCore.Builder
/// <param name="app">The <see cref="IApplicationBuilder"/> to add the middleware to.</param>
/// <param name="transform">A function that asynchronously transforms one <see cref="ClaimsPrincipal"/> to another.</param>
/// <returns>A reference to this instance after the operation has completed.</returns>
public static IApplicationBuilder UseClaimsTransformation(this IApplicationBuilder app, Func<ClaimsPrincipal, Task<ClaimsPrincipal>> transform)
public static IApplicationBuilder UseClaimsTransformation(this IApplicationBuilder app, Func<ClaimsTransformationContext, Task<ClaimsPrincipal>> 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 }
});
}
/// <summary>
/// Adds the <see cref="ClaimsTransformationMiddleware"/> middleware to the specified <see cref="IApplicationBuilder"/>, which enables claims transformation capabilities.
/// </summary>

View File

@ -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; }
}
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -9,11 +9,11 @@ namespace Microsoft.AspNetCore.Authentication
{
public class ClaimsTransformer : IClaimsTransformer
{
public Func<ClaimsPrincipal, Task<ClaimsPrincipal>> OnTransform { get; set; }
public Func<ClaimsTransformationContext, Task<ClaimsPrincipal>> OnTransform { get; set; }
public virtual Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
public virtual Task<ClaimsPrincipal> TransformAsync(ClaimsTransformationContext context)
{
return OnTransform?.Invoke(principal) ?? Task.FromResult(principal);
return OnTransform?.Invoke(context) ?? Task.FromResult(context.Principal);
}
}
}

View File

@ -14,8 +14,8 @@ namespace Microsoft.AspNetCore.Authentication
/// <summary>
/// Provides a central transformation point to change the specified principal.
/// </summary>
/// <param name="principal">The principal to transform.</param>
/// <param name="context"><see cref="ClaimsTransformationContext"/> containing principal to transform and current HttpContext.</param>
/// <returns>The transformed principal.</returns>
Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal);
Task<ClaimsPrincipal> TransformAsync(ClaimsTransformationContext context);
}
}

View File

@ -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);
}
}
});

View File

@ -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) =>
{