ASP.NET Core 2.0 disable automatic challenge

前端 未结 8 882
萌比男神i
萌比男神i 2020-11-28 13:40

After upgrading my ASP.NET Core project to 2.0, attempts to access protected endpoints no longer returns 401, but redirects to an (non-existing) endpoint in an attempt to le

相关标签:
8条回答
  • 2020-11-28 13:50

    I found that in most cases the solution is to override

    OnRedirectToLogin

    But in my app I was using multiple authentication policies and overriding of the OnRedirectToLogin did not work for me. The solution in my case it was to add a simple middleware to redirect the incoming request.

    app.Use(async (HttpContext context, Func<Task> next) => {
        await next.Invoke(); //execute the request pipeline
    
        if (context.Response.StatusCode == StatusCodes.Status302Found && context.Response.Headers.TryGetValue("Location", out var redirect)) {
            var v = redirect.ToString();
            if (v.StartsWith($"{context.Request.Scheme}://{context.Request.Host}/Account/Login")) {
                context.Response.Headers["Location"] = $"{context.Request.Scheme}://{context.Request.Host}{context.Request.Path}";
                context.Response.StatusCode = 401;
            }
        }
    });
    
    
    0 讨论(0)
  • 2020-11-28 13:52

    I'm not sure how to generate the 401 error, however if you use the:

    o.AccessDeniedPath = "{path to invalid}";
    

    This will allow you to redirect somewhere when the challenge has failed.

    0 讨论(0)
  • 2020-11-28 13:55

    This is the source code of CookieAuthenticationEvents.OnRedirectToLogin :

    public Func<RedirectContext<CookieAuthenticationOptions>, Task> OnRedirectToLogin { get; set; } = context =>
    {
        if (IsAjaxRequest(context.Request))
        {
            context.Response.Headers["Location"] = context.RedirectUri;
            context.Response.StatusCode = 401;
        }
        else
        {
            context.Response.Redirect(context.RedirectUri);
        }
        return Task.CompletedTask;
    };
    

    You can add "X-Requested-With: XMLHttpRequest" Header to the request while making API calls from your client.

    0 讨论(0)
  • 2020-11-28 13:59

    As pointed out by some of the other answers, there is no longer a setting to turn off automatic challenge with cookie authentication. The solution is to override OnRedirectToLogin:

    services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
            .AddCookie(options =>
             {                 
                 options.Events.OnRedirectToLogin = context =>
                 {
                     context.Response.Headers["Location"] = context.RedirectUri;
                     context.Response.StatusCode = 401;
                     return Task.CompletedTask;
                 };
             });
    

    This may change in the future: https://github.com/aspnet/Security/issues/1394

    0 讨论(0)
  • 2020-11-28 14:00

    According to this article:

    In 1.x, the AutomaticAuthenticate and AutomaticChallenge properties were intended to be set on a single authentication scheme. There was no good way to enforce this.

    In 2.0, these two properties have been removed as flags on the individual AuthenticationOptions instance and have moved into the base AuthenticationOptions class. The properties can be configured in the AddAuthentication method call within the ConfigureServices method of Startup.cs

    services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme);
    

    Alternatively, use an overloaded version of the AddAuthentication method to set more than one property. In the following overloaded method example, the default scheme is set to CookieAuthenticationDefaults.AuthenticationScheme. The authentication scheme may alternatively be specified within your individual [Authorize] attributes or authorization policies.

    services.AddAuthentication(options => {
        options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
    });
    

    Define a default scheme in 2.0 if one of the following conditions is true:

    • You want the user to be automatically signed in
    • You use the [Authorize] attribute or authorization policies without specifying schemes

    An exception to this rule is the AddIdentity method. This method adds cookies for you and sets the default authenticate and challenge schemes to the application cookie IdentityConstants.ApplicationScheme. Additionally, it sets the default sign-in scheme to the external cookie IdentityConstants.ExternalScheme.

    Hope this help you.

    0 讨论(0)
  • 2020-11-28 14:02

    Similiar to @Serverin, setting the OnRedirectToLogin of the Application Cookie worked, but must be done in statement following services.AddIdentity in Startup.cs:ConfigureServices:

    services.ConfigureApplicationCookie(options => {
      options.Events.OnRedirectToLogin = context => {
        context.Response.Headers["Location"] = context.RedirectUri;
        context.Response.StatusCode = 401;
        return Task.CompletedTask;
      };
    });
    
    0 讨论(0)
提交回复
热议问题