根据this question的答案,我默认添加了对所有内容的授权,使用以下代码:
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;
});
}
但是,当有人试图访问未经授权的内容时,会返回一个(看似默认的)重定向网址(http://foo.bar/Account/Login?ReturnUrl=%2Fapi%2Ffoobar%2F)。
我希望它仅返回HTTP 401,而不是重定向。
如何在ASP.NET 5中为WebAPI执行此操作?
答案 0 :(得分:21)
我在Angular2 + ASP.NET Core应用程序中遇到过这个问题。我设法通过以下方式修复它:
if word.isdigit() and len(word) == 10:
如果这对您不起作用,您可以尝试使用以下方法:
services.AddIdentity<ApplicationUser, IdentityRole>(config => {
// ...
config.Cookies.ApplicationCookie.AutomaticChallenge = false;
// ...
});
Asp.Net Core 2.0更新
现在可以通过以下方式配置Cookie选项:
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);
}
};
// ...
}
答案 1 :(得分:5)
通过网址,您会被重定向到我假设您正在使用Cookie身份验证。
您应该通过将LoginPath
的{{1}}属性设置为null或由其中一个用户清空为described来获得所需的结果。
CookieAuthenticationOptions
当时可能正在工作但是不再工作(因为this更改了)。
我已为此提交bug on GitHub。
一旦修复后我会更新答案。
答案 2 :(得分:1)
请注意,只有当您想使用自己的身份验证机制时,才应使用CookieAuthentication
,例如绕过Identity
提供商,而我们大多数人并非如此。
默认Identity
提供商使用场景后面的CookieAuthenticationOptions
,您可以像下面一样对其进行配置。
services.AddIdentity<ApplicationUser, IdentityRole>(o =>
{
o.Password.RequireDigit = false;
o.Password.RequireUppercase = false;
o.Password.RequireLowercase = false;
o.Password.RequireNonAlphanumeric = false;
o.User.RequireUniqueEmail = true;
o.Cookies.ApplicationCookie.LoginPath = null; // <-----
})
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
在版本1.0.0
答案 3 :(得分:1)
如果它有帮助,下面是我的答案 - 使用dotnet 1.0.1
它基于Darkseal的答案,除了我必须添加行ctx.Response.WriteAsync()来停止重定向到默认的401 URL(帐户/登录)
// Adds identity to the serviceCollection, so the applicationBuilder can UseIdentity
services.AddIdentity<ApplicationUser, IdentityRole>(options =>
{
//note: this has no effect - 401 still redirects to /Account/Login!
//options.Cookies.ApplicationCookie.LoginPath = null;
options.Cookies.ApplicationCookie.Events = new CookieAuthenticationEvents
{
OnRedirectToLogin = ctx =>
{
//for WebApi: prevent aspnet core redirecting to 'Account/Login' on a 401:
if (ctx.Request.Path.StartsWithSegments("/api"))
{
ctx.RedirectUri = null;
ctx.Response.WriteAsync("{\"error\": " + ctx.Response.StatusCode + "}");
}
else
{
ctx.Response.Redirect(ctx.RedirectUri);
}
return Task.FromResult(0);
}
};
})
.AddDefaultTokenProviders();
}
答案 4 :(得分:1)
我有类似的问题。 我通过手动服务解决了这个问题。
ConfigureServices方法:
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";
});
配置方法:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseCors("AllowAllHeaders");
app.UseAuthentication();
app.UseMvc();
}
我使用的是aspnet core 2.0,IdentityServer 4和aspnet标识。
答案 5 :(得分:0)
在Startup
中使用此代码:
services.ConfigureApplicationCookie(options =>
{
options.LoginPath = $"/Account/Login";
options.LogoutPath = $"/Account/Logout";
options.AccessDeniedPath = $"/Account/AccessDenied";
options.Events = new CookieAuthenticationEvents()
{
OnRedirectToLogin = (ctx) =>
{
if (ctx.Request.Path.StartsWithSegments("/api") && ctx.Response.StatusCode == 200)
ctx.Response.StatusCode = 401;
return Task.CompletedTask;
},
OnRedirectToAccessDenied = (ctx) =>
{
if (ctx.Request.Path.StartsWithSegments("/api") && ctx.Response.StatusCode == 200)
ctx.Response.StatusCode = 403;
return Task.CompletedTask;
}
};
});