How to request authentication from custom middleware in ASP.NET Core 2.0
Asked Answered
T

2

7

I have two custom ASP.NET Core middlewares: one for authentication (that registers its own authentication scheme) and a second one for some business work.

How can I use the authentication middleware in another middleware? I can use authentication easily in an MVC like that:

 services.AddMvc(config =>
 {
     var policy = new AuthorizationPolicyBuilder()
                      .RequireAuthenticatedUser()
                      .Build();
     config.Filters.Add(new AuthorizeFilter(policy));
 });

I can also provide my own AuthenticationSchemeProvider to use different authentication schemes based on the requested URL. But the authentication middleware only runs for MVC controllers. I want it to run also before my custom middleware runs. Is it possible to do that?

Travel answered 11/5, 2018 at 10:55 Comment(1)
Here's an example of invoking authz yourself. github.com/aspnet/AuthSamples/blob/…Symmetrize
T
11

In custom middleware method Invoke() call ChallengeAsync() if user is not authenticated:

public async Task Invoke(HttpContext httpContext, IServiceProvider serviceProvider)
{
    if (!httpContext.User.Identity.IsAuthenticated)
    {
        await httpContext.ChallengeAsync();
    }
    else { /* logic here */ }
}

NuGet package Microsoft.AspNetCore.Authentication.Abstractions has to be added.

Above code will run the default authentication service to authenticate user. If the default one is your custom authentication middleware, then it will be called.

Travel answered 14/5, 2018 at 12:8 Comment(2)
await httpContext.ChallengeAsync(); was helpful. But httpContext.User.Identity.IsAuthenticated is always falseConidiophore
@FemilShajin You may need to add a check on the context.Request.Path depending on which authentication provider you're using. See #53089014 for an example.Tangleberry
H
2

This is based on Rython's answer for the specific case of using Windows Authentication, but also allows designed controllers to use other type of authentication:

/// <summary>
/// checks if current request resource can be accesses without being Windows-authenticated
/// </summary>
/// <param name="context">http context</param>
/// <returns>true if non-Windows is allowed. Otherwise, false</returns>
public static bool IsAllowedWithoutWindowsAuth(HttpContext context)
{
    bool isAllowedWithoutWindowsAuth = context.Request.Method == "OPTIONS" ||
                                       AllowedControllers.Any(c =>
                                       {
                                           string path = context.Request.Path.ToString();
                                           return path.StartsWith(c, StringComparison.InvariantCulture);
                                       });
    return isAllowedWithoutWindowsAuth;
}

// custom middleware code 
public async Task Invoke(HttpContext context)
{
    // anonymous path, skipping
    if (IsAllowedWithoutWindowsAuth(context))
    {
        await _next(context);
        return;
    }

    if (!context.User.Identity.IsAuthenticated)
    {
        await context.ChallengeAsync("Windows");
        return;
    }

    // other code here
    await _next(context);
 }
Heckle answered 30/5, 2019 at 12:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.