Is there a way to add claims in an ASP.NET Core middleware after Authentication?

谁都会走 提交于 2021-02-17 15:15:32

问题


I have this in my startup:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();
    app.UseSwaggerWithUi();

    app.UseAuthentication();
    app.UseMiddleware<SomeMiddleware>();

    app.UseMvc();
}

I need to add some additional claims AFTER the user is authenticated, but the middleware Invoke function always fires before Auth (HttpContext.User.Identity.IsAuthenticated is false). But when it hits the controller the user is authenticated fine.

Any idea what to do here? I've tried to put "app.UseAuthentication()" after calling app.UseMiddleware but it has no affect.

I'm currently using multiple Authentication schemes. I'm not sure if that has an affect.


回答1:


Yes it's possible, but instead of adding to the list of existing claims you have to add a new identity of type ClaimsIdentity.

public class SomeMiddleware
{
    private readonly RequestDelegate _next;

    public SomeMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext httpContext)
    {
        if (httpContext.User != null && httpContext.User.Identity.IsAuthenticated)
        {
            var claims = new List<Claim>
            {
                new Claim("SomeClaim", "SomeValue")
            };

            var appIdentity = new ClaimsIdentity(claims);
            httpContext.User.AddIdentity(appIdentity);                
        }

        await _next(httpContext);
    }
}



回答2:


You can add another middleware immediately after the UseAuthentication() to add claims :

app.UseAuthentication();
app.Use(async(context, next)=>{
    if(context.User !=null && context.User.Identity.IsAuthenticated){
        // add claims here 
        context.User.Claims.Append(new Claim("type-x","value-x"));
    }
    await next();
});

//  call other middlewares 
app.UseMiddleware<SomeMiddleware>();



回答3:


You could write your own middleware to add new claims.

public class YourCustomMiddleware
{
    private readonly RequestDelegate _next;

    public YourCustomMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext httpContext)
    {
        if (httpContext.User != null && httpContext.User.Identity.IsAuthenticated)
        {

            httpContext.User.Identities.FirstOrDefault().AddClaim(new Claim("your claim", "your field"));
        }
        await _next(httpContext);
    }
}

and in your app startup

app.UseAuthentication();
app.UseMiddleware<YourCustomMiddleware>();



回答4:


The preferred way for .NET Core 2.x is to use IClaimsTransformation, this has a single method TransformAsync(ClaimsPrincipal) with the note

Provides a central transformation point to change the specified principal. Note: this will be run on each AuthenticateAsync call, so its safer to return a new ClaimsPrincipal if your transformation is not idempotent.

Depending on the nature of the enrichment I add the claims to the existing authenticated identity or create a new identity with and mark that as authenticated. With the second idea you can make your method idempotent by checking for your custom identity before attempting the enrichment.




回答5:


It depends on what do you want to do and which scheme you use.

For example, if you use JwtBearer then you could utilize JwtBearerOptions.Events to handle particular events raised by the middleware. You need to set that in your ConfigureServices method of Startup class.

That would give you more granular control of what precise case you want to have your Claims added to, for example, OnTokenValidated.



来源:https://stackoverflow.com/questions/53292286/is-there-a-way-to-add-claims-in-an-asp-net-core-middleware-after-authentication

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!