问题
When I request a controller action that is [Authorize] decorated instead of being redirected to the login page I receive a 401 error.
This is a .net core mvc app using the identity template running on IIS express.
When i run the app from program.cs the redirect to login works fine. I've added explicit directions to for the cookie authentication to use the /Account/Login redirect both for configuration and services section, as well as configuring Identity to perform this redirect.
I can't get it to work. Below is my StartUp class, what should I change to make it work in IIS express?:
public class Startup
{
private MapperConfiguration _mapperConfiguration { get; set; }
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
if (env.IsDevelopment())
{
// For more details on using the user secret store see http://go.microsoft.com/fwlink/?LinkID=532709
builder.AddUserSecrets();
}
builder.AddEnvironmentVariables();
Configuration = builder.Build();
_mapperConfiguration = new MapperConfiguration(cfg =>
{
cfg.AddProfile(new AutoMapperProfileConfiguration());
});
}
public IConfigurationRoot Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<ApplicationUser, IdentityRole>(
option => {
option.Cookies.ApplicationCookie.LoginPath = "/Account/Login";
option.Cookies.ApplicationCookie.AutomaticChallenge = true;
option.Cookies.ApplicationCookie.AutomaticAuthenticate = true;
})
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddDataProtection();
services.AddMvc();
services.AddSignalR();
// Add application services.
services.AddTransient<IEmailSender, AuthMessageSender>();
services.AddTransient<ISmsSender, AuthMessageSender>();
services.Configure<AuthMessageSenderOptions>(Configuration);
services.Configure<IISOptions>(options => options.AutomaticAuthentication = true);
services.AddSingleton<IMapper>(sp => _mapperConfiguration.CreateMapper());
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, ApplicationDbContext context, RoleManager<IdentityRole> roleManager)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
app.UseStaticFiles();
app.UseIdentity();
// Add external authentication middleware below. To configure them please see http://go.microsoft.com/fwlink/?LinkID=532715
//app.UseStatusCodePagesWithReExecute("/Home/Error/{0}");
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationScheme = "MyCookies",
SlidingExpiration = true,
AutomaticAuthenticate = true,
AutomaticChallenge = true,
LoginPath = new PathString("/Account/Login")
});
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
routes.MapRoute(
name: "index",
template: "{controller=Home}/{id?}",
defaults: new { action = "Index" });
});
app.UseSignalR();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
app.UseBrowserLink();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
MyDbInit.Init(context, roleManager);
}
}
回答1:
I had this same problem all night and could not find a solution to it. Running the site directly from Kestrel redirected fine, but through IIS or IIS Express it simply would not redirect - it would go to a white page.
After posting to the Identity Git about it, I realized that my template was set up to run under 1.0.1 of the framework, not 1.1.0. I updated it to use 1.1.0 and updated all the Nuget packages to 1.1.0 and now it is redirecting in IIS and IIS Express properly.
I'm not sure if the package updates "fixed" something that was screwy, or if this was simply a problem with 1.0.1 that was fixed in 1.1.0.
https://blogs.msdn.microsoft.com/webdev/2016/11/16/announcing-asp-net-core-1-1/
回答2:
Identity adds cookie authentication automatically. You're adding it a second time in Configure.
When you add the second instance you're setting both the automatic properties, so now two middlewares are trying to do the redirection, and that behaviour is "undefined" (where undefined == "Going to seriously mess things up").
回答3:
This line inside Configure method in Startup class, resolve me problem:
public class Startup
{
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
...
app.UseAuthentication(); // <= This line
app.UseMvc(routes =>
{
...
});
}
}
来源:https://stackoverflow.com/questions/40776017/cant-get-net-core-mvc-to-redirect-401-to-account-login