J'ai mis à jour les packages bêta-8 du framework ASP.NET 5 avec des packages RC sur une application fonctionnant précédemment. Après l'avoir exécuté, une erreur suivante s'est produite dans le processus de démarrage:
InvalidOperationException: aucun gestionnaire d'authentification n'est configuré pour gérer le schéma: automatique Microsoft.AspNet.Http.Authentication.Internal.DefaultAuthenticationManager.d__12.MoveNext ()
var defaultPolicy =
new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
services.AddMvc(setup =>
{
setup.Filters.Add(new AuthorizeFilter(defaultPolicy)); // Error occurs here
});
Si quelqu'un avait un problème similaire, j'apprécierais votre idée ou solution sur ce qui aurait pu mal tourner. Une explication de cette exception est également appréciée.
Startup.cs
using Autofac;
using Autofac.Extensions.DependencyInjection;
using Microsoft.AspNet.Authorization;
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Hosting;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Mvc.Filters;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.PlatformAbstractions;
using SuperUserMVC.Configuration;
using SuperUserMVC.Extensions;
using SuperUserMVC.GlobalModules;
using System;
namespace SuperUserMVC
{
public class Startup
{
public IConfigurationRoot Configuration { get; set; }
// Entry point for the application.
public static void Main(string[] args) => WebApplication.Run<Startup>(args);
public Startup(IHostingEnvironment env, IApplicationEnvironment appEnv)
{
var builder = new ConfigurationBuilder()
.SetBasePath(appEnv.ApplicationBasePath)
.AddJsonFile("appsettings.json");
Configuration = builder.Build();
}
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.Configure<AppSettingsBase>(Configuration.GetSection("AppSettingsBase"));
services.Configure<ConnectionString>(Configuration.GetSection("ConnectionString"));
services.AddSqlServerCache(cache =>
{
cache.ConnectionString = Configuration.Get<string>("ASPState:ConnectionString");
cache.SchemaName = Configuration.Get<string>("ASPState:Schema");
cache.TableName = Configuration.Get<string>("ASPState:Table");
});
services.AddSession(session =>
{
session.IdleTimeout = TimeSpan.FromMinutes(120);
});
// Only allow authenticated users.
var defaultPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
// Add MVC services to the services container.
services.AddMvc(setup =>
{
setup.Filters.Add(new AuthorizeFilter(defaultPolicy));
});
var builder = new ContainerBuilder();
builder.RegisterModule(new AutofacModule());
builder.Populate(services);
var container = builder.Build();
return container.Resolve<IServiceProvider>();
}
public void Configure(IApplicationBuilder app, IHttpContextAccessor httpContextAccessor)
{
// Catch unhandled exception in pipeline.
bool isProductionEnvironment = Configuration.Get<bool>("environmentVariables:isProductionEnvironment");
app.UseCustomUnhandledException(isProductionEnvironment, Configuration.Get<string>("defaultErrorPagePath"));
// Log requests.
app.UseVisitLogger(isProductionEnvironment);
// Session must be used before MVC routes.
app.UseSession();
// Configure the HTTP request pipeline.
app.UseCookieAuthentication(options =>
{
options.AuthenticationScheme = "Cookies";
options.LoginPath = new PathString("/Account/Login/");
options.AccessDeniedPath = new PathString("/Account/Forbidden/");
options.CookieName = "MyCookie";
options.AutomaticAuthenticate = true;
options.SessionStore = new MemoryCacheSessionStore();
});
AutoMapperInitializer.Init();
app.UseStaticFiles();
// Route configuration.
app.UseMvc(routes =>
{
routes.MapRoute(
name: "AreaDefault",
template: "{area:exists=Demo}/{controller=Home}/{action=Index}/{id?}"
);
routes.MapRoute(
name: "Default",
template: "{controller=Home}/{action=Index}/{id?}"
);
});
}
}
}
Essayez de définir options.AutomaticChallenge = true;
dans vos options de cookies et cela devrait fonctionner.
options.AutomaticAuthentication
a été divisé en options.AutomaticAuthenticate
et options.AutomaticChallenge
. Si le dernier est laissé à false
, une exception est levée car aucun middleware d'authentification ne gère le défi appliqué par le filtre d'autorisation.
J'espère que cela aidera quelqu'un d'autre parce que je viens de passer beaucoup de temps à gérer cette erreur même si j'avais défini AutomaticChallenge = true
.
Il s'avère que vous obtiendrez la même erreur si vous mettez app.UseIdentity();
après app.UseMvc(routes => ...)
. Maintenant que je connais la réponse, c'est évident. C'est parce que tout ce middleware se produit dans l'ordre dans lequel vous l'ajoutez.
Cela provoque l'erreur "aucun gestionnaire d'authentification n'est configuré":
public void Configure(...)
{
app.UseMvc(routes => { routes.MapRoute(...) }; );
app.UseIdentity();
}
Cela ne provoque pas l'erreur:
public void Configure(...)
{
app.UseIdentity();
app.UseMvc(routes => { routes.MapRoute(...); });
}
Mettez ceci sur la méthode Configure.
app.UseIdentity();
Le problème a été résolu pour moi en m'assurant que le schéma de cookies était systématiquement nommé partout où il était référencé. par exemple.:
public void ConfigureServices(IServiceCollection services)
{
// if using IdentityServer4
var builder = services.AddIdentityServer(options =>
{
options.AuthenticationOptions.AuthenticationScheme = Constants.DefaultCookieAuthenticationScheme;
...
})
services.AddIdentity<MyUser, IdentityRole>(options =>
{
options.Cookies.ApplicationCookie.AuthenticationScheme = Constants.DefaultCookieAuthenticationScheme;
...
}
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
...
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationScheme = Constants.DefaultCookieAuthenticationScheme,
AutomaticAuthenticate = false,
AutomaticChallenge = true
});
}
Et lors de l'interaction avec le middleware d'authentification. par exemple.:
await HttpContext.Authentication.SignInAsync(Constants.DefaultCookieAuthenticationScheme, cp);
Si vous utilisez app.UseIdentity();
et d'autres middleware de connexion tels que UseFacebookAuthentication
assurez-vous que app.UseFacebookAuthentication()
est APRÈS app.UseIdentity();
.
une autre possibilité manque le paramètre suivant dans Configurer
app.UseCookieAuthentication();
Bien qu'il soit tentant de placer une grande partie de nos paramètres de configuration dans le fichier startup.cs
, Il semble que la façon préférée de faire les choses est de définir votre app.UseCookieAuthentication()
- sans options - dans le startup.cs
, puis placez toutes les "options" et autres détails dans un fichier séparé.
Un peu comme ce que nous faisions avec la façon dont le fichier Global.asax
Avait des pointeurs vers les fichiers du dossier App_Start
Dans Asp.Net vBefore.
J'ai souffert d'une douleur similaire en essayant de configurer EF/Sql dans startup.cs
, Et en déplaçant toutes les "options" en dehors de startup.cs
, Les choses fonctionnaient beaucoup mieux.
AUSSI: prenez note du commentaire de Fredy Wenger à votre question qui souligne le "renommage" de nombreux espaces de noms de v -8beta à v -RC1-final.