Re-challenge authenticated users in ASP.NET Core

2020-06-16 04:19发布

I'm running into some issues with the authentication pipeline in ASP.NET Core. My scenario is that I want to issue a challenge to a user who is already authenticated using OpenID Connect and Azure AD. There are multiple scenarios where you'd want to do that, for example when requesting additional scopes in a AAD v2 endpoint scenario.

This works like a charm in ASP.NET MVC, but in ASP.NET Core MVC the user is being redirected to the Access Denied-page as configured in the cookie authentication middleware. (When the user is not logged in, issuing a challenge works as expected.)

After a couple of hours searching the web and trying different parameters for my middleware options, I'm beginning to suspect that either I'm missing something obvious, or this behavior is by design and I need to solve my requirement some other way. Anyone any ideas on this?

EDIT: the relevant parts of my Startup.cs look like this:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();

        services.AddAuthentication(
            SharedOptions => SharedOptions.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme);
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        // <snip...>

        app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationScheme = CookieAuthenticationDefaults.AuthenticationScheme });

        var options = new OpenIdConnectOptions
        {
            AuthenticationScheme = OpenIdConnectDefaults.AuthenticationScheme,
            ClientId = ClientId,
            Authority = Authority,
            CallbackPath = Configuration["Authentication:AzureAd:CallbackPath"],
            ResponseType = OpenIdConnectResponseType.CodeIdToken,
            PostLogoutRedirectUri = "https://localhost:44374/",
            TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
            {
                ValidateIssuer = false
            }
        };
        options.Scope.Add("email");
        options.Scope.Add("offline_access");

        app.UseOpenIdConnectAuthentication(options);
    }

And the Action looks like this:

    public void RefreshSession()
    {
        HttpContext.Authentication.ChallengeAsync(OpenIdConnectDefaults.AuthenticationScheme, new AuthenticationProperties { RedirectUri = "/" });
    }

2条回答
何必那么认真
2楼-- · 2020-06-16 04:53
Try to sign out:

public void RefreshSession()
{
      HttpContext.Authentication.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
      HttpContext.Authentication.SignOutAsync(OpenIdConnectDefaults.AuthenticationScheme);
      HttpContext.Authentication.ChallengeAsync(OpenIdConnectDefaults.AuthenticationScheme, new AuthenticationProperties { RedirectUri = "/" });
}
查看更多
劳资没心,怎么记你
3楼-- · 2020-06-16 05:16

I found a hint and the solution here: https://github.com/aspnet/Security/issues/912. ChallengeBehavior.Unauthorized is the "key".

This post gives the current (november 2016 - ASPNet 1.0.1) workaround: https://joonasw.net/view/azure-ad-b2c-with-aspnet-core

You'll need a new ActionResult to be able to call the AuthauticationManager.ChallengeAsync with the ChallengeBehavior.Unauthorized behavior.

Once the issue https://github.com/aspnet/Mvc/issues/5187 will be sucessfully closed, this should be integrated.

I tested it and it worked perfectly well (my goal was simply to extend Google scopes on a per user basis).

查看更多
登录 后发表回答