IClaimsTransofrmer updated to take ClaimsTransformationContext instead of ClaimsPrincipal in TransformAsync method. #718
This commit is contained in:
parent
4bfeba2a3c
commit
f5c1c45db2
|
|
@ -35,7 +35,7 @@ namespace Microsoft.AspNetCore.Builder
|
||||||
/// <param name="app">The <see cref="IApplicationBuilder"/> to add the middleware to.</param>
|
/// <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>
|
/// <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>
|
/// <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)
|
if (app == null)
|
||||||
{
|
{
|
||||||
|
|
@ -46,12 +46,12 @@ namespace Microsoft.AspNetCore.Builder
|
||||||
throw new ArgumentNullException(nameof(transform));
|
throw new ArgumentNullException(nameof(transform));
|
||||||
}
|
}
|
||||||
|
|
||||||
return app.UseClaimsTransformation(new ClaimsTransformationOptions
|
return app.UseClaimsTransformation(new ClaimsTransformationOptions
|
||||||
{
|
{
|
||||||
Transformer = new ClaimsTransformer { OnTransform = transform }
|
Transformer = new ClaimsTransformer { OnTransform = transform }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds the <see cref="ClaimsTransformationMiddleware"/> middleware to the specified <see cref="IApplicationBuilder"/>, which enables claims transformation capabilities.
|
/// Adds the <see cref="ClaimsTransformationMiddleware"/> middleware to the specified <see cref="IApplicationBuilder"/>, which enables claims transformation capabilities.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -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; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Http.Features.Authentication;
|
using Microsoft.AspNetCore.Http.Features.Authentication;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Authentication
|
namespace Microsoft.AspNetCore.Authentication
|
||||||
|
|
@ -12,10 +13,12 @@ namespace Microsoft.AspNetCore.Authentication
|
||||||
public class ClaimsTransformationHandler : IAuthenticationHandler
|
public class ClaimsTransformationHandler : IAuthenticationHandler
|
||||||
{
|
{
|
||||||
private readonly IClaimsTransformer _transform;
|
private readonly IClaimsTransformer _transform;
|
||||||
|
private readonly HttpContext _httpContext;
|
||||||
|
|
||||||
public ClaimsTransformationHandler(IClaimsTransformer transform)
|
public ClaimsTransformationHandler(IClaimsTransformer transform, HttpContext httpContext)
|
||||||
{
|
{
|
||||||
_transform = transform;
|
_transform = transform;
|
||||||
|
_httpContext = httpContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IAuthenticationHandler PriorHandler { get; set; }
|
public IAuthenticationHandler PriorHandler { get; set; }
|
||||||
|
|
@ -27,8 +30,12 @@ namespace Microsoft.AspNetCore.Authentication
|
||||||
await PriorHandler.AuthenticateAsync(context);
|
await PriorHandler.AuthenticateAsync(context);
|
||||||
if (_transform != null && context?.Principal != null)
|
if (_transform != null && context?.Principal != null)
|
||||||
{
|
{
|
||||||
|
var transformationContext = new ClaimsTransformationContext(_httpContext)
|
||||||
|
{
|
||||||
|
Principal = context.Principal
|
||||||
|
};
|
||||||
context.Authenticated(
|
context.Authenticated(
|
||||||
await _transform.TransformAsync(context.Principal),
|
await _transform.TransformAsync(transformationContext),
|
||||||
context.Properties,
|
context.Properties,
|
||||||
context.Description);
|
context.Description);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,13 +35,17 @@ namespace Microsoft.AspNetCore.Authentication
|
||||||
|
|
||||||
public async Task Invoke(HttpContext context)
|
public async Task Invoke(HttpContext context)
|
||||||
{
|
{
|
||||||
var handler = new ClaimsTransformationHandler(Options.Transformer);
|
var handler = new ClaimsTransformationHandler(Options.Transformer, context);
|
||||||
handler.RegisterAuthenticationHandler(context.GetAuthentication());
|
handler.RegisterAuthenticationHandler(context.GetAuthentication());
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (Options.Transformer != null)
|
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);
|
await _next(context);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,11 +9,11 @@ namespace Microsoft.AspNetCore.Authentication
|
||||||
{
|
{
|
||||||
public class ClaimsTransformer : IClaimsTransformer
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,8 @@ namespace Microsoft.AspNetCore.Authentication
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Provides a central transformation point to change the specified principal.
|
/// Provides a central transformation point to change the specified principal.
|
||||||
/// </summary>
|
/// </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>
|
/// <returns>The transformed principal.</returns>
|
||||||
Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal);
|
Task<ClaimsPrincipal> TransformAsync(ClaimsTransformationContext context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -293,16 +293,16 @@ namespace Microsoft.AspNetCore.Authentication.Cookies
|
||||||
{
|
{
|
||||||
Transformer = new ClaimsTransformer
|
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
|
// REVIEW: Xform runs twice, once on Authenticate, and then once from the middleware
|
||||||
var id = new ClaimsIdentity("xform");
|
var id = new ClaimsIdentity("xform");
|
||||||
id.AddClaim(new Claim("xform", "yup"));
|
id.AddClaim(new Claim("xform", "yup"));
|
||||||
p.AddIdentity(id);
|
context.Principal.AddIdentity(id);
|
||||||
}
|
}
|
||||||
return Task.FromResult(p);
|
return Task.FromResult(context.Principal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -222,7 +222,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
|
||||||
ClientId = "Test Id",
|
ClientId = "Test Id",
|
||||||
ClientSecret = "Test Secret"
|
ClientSecret = "Test Secret"
|
||||||
},
|
},
|
||||||
async context =>
|
async context =>
|
||||||
{
|
{
|
||||||
var req = context.Request;
|
var req = context.Request;
|
||||||
var res = context.Response;
|
var res = context.Response;
|
||||||
|
|
@ -273,7 +273,7 @@ namespace Microsoft.AspNetCore.Authentication.Google
|
||||||
{
|
{
|
||||||
var transaction = await sendTask;
|
var transaction = await sendTask;
|
||||||
Assert.Equal(HttpStatusCode.Redirect, transaction.Response.StatusCode);
|
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
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -774,12 +774,12 @@ namespace Microsoft.AspNetCore.Authentication.Google
|
||||||
AutomaticAuthenticate = true
|
AutomaticAuthenticate = true
|
||||||
});
|
});
|
||||||
app.UseGoogleAuthentication(options);
|
app.UseGoogleAuthentication(options);
|
||||||
app.UseClaimsTransformation(p =>
|
app.UseClaimsTransformation(context =>
|
||||||
{
|
{
|
||||||
var id = new ClaimsIdentity("xform");
|
var id = new ClaimsIdentity("xform");
|
||||||
id.AddClaim(new Claim("xform", "yup"));
|
id.AddClaim(new Claim("xform", "yup"));
|
||||||
p.AddIdentity(id);
|
context.Principal.AddIdentity(id);
|
||||||
return Task.FromResult(p);
|
return Task.FromResult(context.Principal);
|
||||||
});
|
});
|
||||||
app.Use(async (context, next) =>
|
app.Use(async (context, next) =>
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue