如何从ASP.NET Core webapi中删除重定向并返回HTTP 401?

Gee*_*ten 16 asp.net authorization asp.net-web-api asp.net-core

关于这个问题的答案,我默认使用以下代码添加了对所有内容的授权:

public void ConfigureServices(IServiceCollection aServices)
{
  aServices.AddMvc(options =>
  {
     var lBuilder = new AuthorizationPolicyBuilder().RequireAuthenticatedUser();

     var lFilter = new AuthorizeFilter(lBuilder.Build());
     options.Filters.Add(lFilter);
   });

   aServices.AddMvc();
}

public void Configure(IApplicationBuilder aApp, IHostingEnvironment aEnv, ILoggerFactory aLoggerFactory)
{
  aApp.UseCookieAuthentication(options =>
  {
    options.AuthenticationScheme = "Cookies";
    options.AutomaticAuthentication = true;
  });
}
Run Code Online (Sandbox Code Playgroud)

但是,当有人试图访问未经授权的内容时,它会返回一个(看似默认的)重定向URL(http://foo.bar/Account/Login?ReturnUrl=%2Fapi%2Ffoobar%2F).

我希望它只返回HTTP 401,而不是重定向.

如何在ASP.NET 5中为WebAPI执行此操作?

Dar*_*eal 24

我在Angular2 + ASP.NET Core应用程序中遇到了这个问题.我设法通过以下方式修复它:

services.AddIdentity<ApplicationUser, IdentityRole>(config =>   {
    // ...
    config.Cookies.ApplicationCookie.AutomaticChallenge = false;
    // ...
});
Run Code Online (Sandbox Code Playgroud)

如果这不适合您,您可以尝试使用以下方法:

services.AddIdentity<ApplicationUser, IdentityRole>(config =>   {
    // ...
    config.Cookies.ApplicationCookie.Events = new CookieAuthenticationEvents
    {
       OnRedirectToLogin = ctx =>
       {
           if (ctx.Request.Path.StartsWithSegments("/api")) 
           {
               ctx.Response.StatusCode = (int) HttpStatusCode.Unauthorized;
               // added for .NET Core 1.0.1 and above (thanks to @Sean for the update)
               ctx.Response.WriteAsync("{\"error\": " + ctx.Response.StatusCode + "}");
           }
           else
           {
               ctx.Response.Redirect(ctx.RedirectUri);
           }
           return Task.FromResult(0);
       }
    };
    // ...
}
Run Code Online (Sandbox Code Playgroud)

Asp.Net Core 2.0的更新

Cookie选项现在按以下方式配置:

services.ConfigureApplicationCookie(config =>
            {
                config.Events = new CookieAuthenticationEvents
                {
                    OnRedirectToLogin = ctx => {
                        if (ctx.Request.Path.StartsWithSegments("/api"))
                        {
                            ctx.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
                        }
                        else {
                            ctx.Response.Redirect(ctx.RedirectUri);
                        }
                        return Task.FromResult(0);
                    }
                };
            });
Run Code Online (Sandbox Code Playgroud)


mbu*_*nik 5

通过网址,您被重定向到我假设您正在使用cookie身份验证.

应该通过将其LoginPath属性设置CookieAuthenticationOptions为null或空来获得所需的结果,其中一个用户所述.

app.UseCookieAuthentication(options =>
        {
            options.LoginPath = "";
        });
Run Code Online (Sandbox Code Playgroud)

那可能是当时的工作,但它不再起作用了(因为这个变化).

我已经在GitHub上提交了一个bug.

一旦修复完毕,我会更新答案.


小智 5

我有类似的问题。我通过手动添加服务解决了这个问题。

配置服务方法:

    services.AddTransient<IUserStore<User>, UserStore<User, IdentityRole, ApplicationDbContext>>();   
    services.AddTransient<IPasswordHasher<User>, PasswordHasher<User>>();
    services.AddTransient<IUserValidator<User>, UserValidator<User>>();
    services.AddTransient<ILookupNormalizer, UpperInvariantLookupNormalizer>();
    services.AddTransient<IPasswordValidator<User>, PasswordValidator<User>>();
    services.AddTransient<IdentityErrorDescriber, IdentityErrorDescriber>();
    services.AddTransient<ILogger<UserManager<User>>, Logger<UserManager<User>>>();
    services.AddTransient<UserManager<User>>();

    services.AddMvcCore()
    .AddJsonFormatters()
    .AddAuthorization();


    services.AddCors(options=> {
    options.AddPolicy("AllowAllHeaders", (builder) => {
        builder.WithOrigins("*").AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin().WithExposedHeaders("WWW-Authenticate"); ;
    });
});


    services.AddAuthentication(options=> {
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
    .AddIdentityServerAuthentication(options =>
    {
        options.Authority = "http://localhost:5000";
        options.RequireHttpsMetadata = false;
        options.ApiName = "api1";
        options.ApiSecret = "secret";
    });
Run Code Online (Sandbox Code Playgroud)

配置方法:

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

    app.UseCors("AllowAllHeaders");
    app.UseAuthentication();
    app.UseMvc();

}
Run Code Online (Sandbox Code Playgroud)

我正在使用 aspnet core 2.0、IdentityServer 4 和 aspnet Identity。

  • 就我而言,问题是我使用的是“services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)”。我以为它会覆盖所有参数。显然我错了。您需要使用“JwtBearerDefaults.AuthenticationScheme;”覆盖“options.DefaultChallengeScheme”,然后它才能工作。在 *ASP.NET Core 预览版 3* 上测试 (2认同)