Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

No authentication handler is configured to handle the scheme: Automatic

I updated ASP.NET 5 framework beta-8 packages with RC ones on previously working application. After I got it running next error occured in the startup process:

InvalidOperationException: No authentication handler is configured to handle the scheme: Automatic 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
});

If anyone had similar problem, I'd appreciate your idea or solution on what might have gone wrong. Explanation of this exception is also appreciated.

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?}"
                );
            });
        }
    }
}
like image 245
msmolcic Avatar asked Nov 20 '15 11:11

msmolcic


4 Answers

Hopefully this will help somebody else because I just spent a lot of time dealing with this error even though I had set AutomaticChallenge = true.

Turns out you will get the same error if you put app.UseIdentity(); after app.UseMvc(routes => ...). Now that I know the answer it's obvious. It's because all this middleware happens in the order you add it.

This causes the "No authentication handler is configured" error:

    public void Configure(...)
    {
        app.UseMvc(routes => { routes.MapRoute(...) }; );

        app.UseIdentity();
    }

This does not cause the error:

    public void Configure(...)
    {
        app.UseIdentity();

        app.UseMvc(routes => { routes.MapRoute(...); });
    }
like image 77
Robert Paulsen Avatar answered Oct 05 '22 22:10

Robert Paulsen


Try setting options.AutomaticChallenge = true; in your cookies options and it should work.

options.AutomaticAuthentication was split into options.AutomaticAuthenticate and options.AutomaticChallenge. If the last one is left to false, an exception is thrown because no authentication middleware handles the challenge applied by the authorization filter.

like image 41
Kévin Chalet Avatar answered Oct 05 '22 22:10

Kévin Chalet


Put this on Configure method.

        app.UseIdentity();
like image 22
celuxcwb Avatar answered Oct 05 '22 22:10

celuxcwb


The problem was solved for me by making sure the cookies scheme was consistently named wherever it was referenced. e.g.:

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
    });
}

And when interacting with the authentication middleware. e.g.:

await HttpContext.Authentication.SignInAsync(Constants.DefaultCookieAuthenticationScheme, cp);
like image 43
TreeAndLeaf Avatar answered Oct 06 '22 00:10

TreeAndLeaf