この質問 の回答に続いて、次のコードを使用して、デフォルトですべてに承認を追加しました。
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;
});
}
しかし、誰かが不正なものにアクセスしようとすると、(デフォルトのように見える)リダイレクトURL( http://foo.bar/Account/Login?ReturnUrl=%2Fapi%2Ffoobar%2F )が返されます。
リダイレクトではなく、HTTP 401のみを返すようにしたい。
ASP.NET 5でWebAPIを使用するにはどうすればよいですか?
Angular2 + ASP.NET Coreアプリケーションでこの問題が発生しました。私はそれを次の方法で修正することができました:
services.AddIdentity<ApplicationUser, IdentityRole>(config => {
// ...
config.Cookies.ApplicationCookie.AutomaticChallenge = false;
// ...
});
これがうまくいかない場合は、代わりに次の方法を試すことができます。
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);
}
};
// ...
}
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);
}
};
});
LoginPath = ""またはnullの設定は、バージョン1.1.0.0では機能しなくなりました。だからこれが私がしたことです:
app.UseCookieAuthentication(new CookieAuthenticationOptions()
{
ExpireTimeSpan = TimeSpan.FromDays(150),
AuthenticationScheme = options.Cookies.ApplicationCookie.AuthenticationScheme,
Events = new CookieAuthenticationEvents
{
OnValidatePrincipal = SecurityStampValidator.ValidatePrincipalAsync,
OnRedirectToLogin = async (context) => context.Response.StatusCode = 401,
OnRedirectToAccessDenied = async (context) => context.Response.StatusCode = 403
},
AutomaticAuthenticate = true,
AutomaticChallenge = true,
});
同様の問題がありました。サービスを手動で追加することでこれを解決しました。
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コア2.0、IdentityServer 4、およびaspnetidentityを使用しています。
それが役立つ場合は、以下が私の答えです-dotnet 1.0.1
デフォルトの401URL(アカウント/ログイン)へのリダイレクトを停止するためにctx.Response.WriteAsync()行を追加する必要があったことを除いて、Darksealの回答に基づいています。
// 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();
}
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
でテスト済み