Начальная страница ASP Core - Логин, но не должна быть - PullRequest
0 голосов
/ 21 октября 2019

Нашей стартовой страницей должен быть Views / Home / index.cshtml, но по какой-то причине по умолчанию всегда используется страница входа. Все выглядит как-то правильно.

Я могу перейти к https://localhost/Home напрямую, не входя в систему, я просто не могу начать там, когда иду прямо в Дом https://localhost

Startup.cs:

public class Startup
{
    public static IConfiguration Configuration { 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)
            .AddEnvironmentVariables();
        Configuration = builder.Build();
    }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddLogging(loggingBuilder => loggingBuilder.AddSerilog(dispose: true));

        services.Configure<CookiePolicyOptions>(options =>
        {
            // This lambda determines whether user consent for non-essential cookies is needed for a given request.
            //Van - 9-29-2019: Cookie policy example: https://quixel.com/cookiepolicy
            options.CheckConsentNeeded = context => false;
            options.MinimumSameSitePolicy = SameSiteMode.None;
        });

        services.AddDbContext<ApplicationDbContext>(options =>
        {
            options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"));
        });

        //services.AddAuthentication(options =>
        //{
        //    options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        //    options.DefaultForbidScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        //    options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        //    options.DefaultSignOutScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        //    options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        //});

        services.AddIdentity<ApplicationUser, IdentityRole>(options =>
        {
            options.SignIn.RequireConfirmedEmail = false;
            options.Password.RequiredLength = 10;
            options.Password.RequireLowercase = true;
            options.Password.RequireUppercase = true;
            options.Password.RequireNonAlphanumeric = true;
            options.Password.RequireDigit = true;
        })
        .AddEntityFrameworkStores<ApplicationDbContext>()
        .AddDefaultTokenProviders();
        services.AddScoped<UserManager<ApplicationUser>>();
        services.AddMemoryCache();
        services.AddDistributedMemoryCache();

        // For session variables, if used. Default IdleTimeout if not accessed = 20 minutes
        services.AddSession(options =>
        {
            options.Cookie.Name = ".H.Session";
            //options.IdleTimeout = TimeSpan.FromMinutes(20);

            //Van - 9-26-2019: Making this essential. The session will hold the evnironment ID if the user has an environment running.
            options.Cookie.IsEssential = true; // GDPR related
        });

        // Microsoft devs discuss expiration settings: https://github.com/aspnet/Identity/issues/1612

        services.Configure<IdentityOptions>(options => 
        {
            options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(10);
            options.Lockout.MaxFailedAccessAttempts = 3;
            options.Lockout.AllowedForNewUsers = true;
        });

        //Van - 9-26-2019: Added because in asp core 3.0 Synchronous operations are disallowed by default
        //TODO: The line "data = await streamReader.ReadToEndAsync();" in TextPlainInputFormatter.cs is the problem. Should work though, its async. using this temp. workaround
        services.Configure<IISServerOptions>(options =>
        {
            options.AllowSynchronousIO = true;
        });

        services.ConfigureApplicationCookie(options =>
        {
            // Cookie settings
            options.Cookie.HttpOnly = true;

            //TODO: the timer below works, but does not automatically redirect, it redirects when you navigate to another page. Find a way to refresh on cookie timeout
            //This also only works if pages are being changed. Not useful for range idleness
            //options.ExpireTimeSpan = TimeSpan.FromMinutes(2);
            //options.ExpireTimeSpan = TimeSpan.FromSeconds(5);
            options.SlidingExpiration = true;

            //Van - 9-20-2019: Because RedirectToLogin is being used, is this necessary? Using redirectUri in RedirectToLogin instead.
            //options.LoginPath = "/Identity/Account/Login";
            options.AccessDeniedPath = "/Identity/Account/AccessDenied";

            //Located in CookieEvents.cs
            options.EventsType = typeof(CookieEvents);
            // options.Events.OnRedirectToLogin = delegateclass. to handle whether to stopenvironment and really logout 
            // - what if guac/range activity is ongoing, bad UX to logout and stopenvironment. CookieAuthenticationEvents delegate class
            // - http://codereform.com/blog/post/asp-net-core-2-0-authentication-with-local-logins-responding-to-backend-changes/
        });

        // Looks like this is policy based, not role based
        services.AddMvc(options =>
                {
                    options.InputFormatters.Add(new TextPlainInputFormatter());
                    options.EnableEndpointRouting = false;
                })
                .AddRazorPagesOptions(options =>
                {
                    options.Conventions.AllowAnonymousToPage("/Home/Index");
                    options.Conventions.AddPageRoute("/Identity/Account/Login", "");
                    options.Conventions.AuthorizeAreaPage("Identity", "/Manage/DownloadPersonalData");
                    options.Conventions.AuthorizeAreaPage("Identity", "/Manage/Index");
                })
                .SetCompatibilityVersion(CompatibilityVersion.Version_3_0)
                .AddSessionStateTempDataProvider();

        //Van - 9/05/2019 - Exceptions get thrown without this line
        System.Environment.SetEnvironmentVariable("AWS_ENABLE_ENDPOINT_DISCOVERY", "false");
        services.AddDefaultAWSOptions(Configuration.GetAWSOptions());

        services.Configure<ArenaClientOptions>(Configuration.GetSection("ArenaClient"));
        services.Configure<HOptions>(Configuration.GetSection("H"));
        services.Configure<BraintreeOptions>(Configuration.GetSection("Braintree"));

        services.AddScoped<ISubscriptionService, SubscriptionService>();
        services.AddScoped<IDashboardService, DashboardService>();
        services.AddTransient<IArenaClient, ArenaClient>();
        services.AddSingleton<ICacheService, CacheService>();

        services.AddTransient<IEmailSenderService, EmailSenderService>();
        services.Configure<EmailSenderOptions>(Configuration.GetSection("EmailSender"));

        services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
        services.AddTransient<CookieEvents>();

        services.AddSingleton<IHubHelperService, HubHelperService>();

        services.AddSignalR();
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, IServiceProvider provider)
    {
        // TODO: ASP.NET Core diagnostics?

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseExceptionHandler("/Home/Error");
            //app.UseDatabaseErrorPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
            // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
            app.UseHsts();
        }

        app.UseAuthentication();
        //app.UseHttpsRedirection();

        app.UseSession();       
        app.UseStaticFiles();
        app.UseStaticFiles(new StaticFileOptions
        {
            FileProvider = new PhysicalFileProvider(
                Path.Combine(Directory.GetCurrentDirectory(), "Utilities")), RequestPath = "/Utilities"
        });
        //app.UseCookiePolicy();

        app.UseSignalR(routes =>
        {
            routes.MapHub<Hubs.RangeHub>("/range");
        });

        //Van - 9-14-2019 - using MVC with defaults should work just fine sense we are not changing the routes
        //  The home controller is being overridden somewhere else
        app.UseMvcWithDefaultRoute();
        //app.UseMvc(routes =>
        //{
        //    routes.MapRoute(
        //        name: "default",
        //        template: "{controller=Home}/{action=Index}/{id?}");
        //});

        CreateRoles(provider);
    }


    private void CreateRoles(IServiceProvider serviceProvider)
    {
        var RoleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>();
        var UserManager = serviceProvider.GetRequiredService<UserManager<ApplicationUser>>();

        var roleNames = Configuration.GetSection("H:Roles").Get<string[]>();
        var superuserEmail = Configuration.GetSection("H:SuperuserEmail").Get<string>();

        Task<IdentityResult> roleResult;

        foreach (var roleName in roleNames)
        {
            Task<bool> roleExist = RoleManager.RoleExistsAsync(roleName);
            roleExist.Wait();

            if (!roleExist.Result)
            {
                roleResult = RoleManager.CreateAsync(new IdentityRole(roleName));
                roleResult.Wait();
            }
        }

        // Change to appSettings value
        var user = UserManager.FindByEmailAsync(superuserEmail);
        user.Wait();

        if (user?.Result != null)
        {
            var hasRole = UserManager.IsInRoleAsync(user.Result, "Superuser");
            hasRole.Wait();

            if (!hasRole.Result)
            {
                Task<IdentityResult> addToRole = UserManager.AddToRoleAsync(user.Result, "Superuser");
                addToRole.Wait();
            }
        }
    }
}

HomeController:

[AllowAnonymous]
public class HomeController : Controller
{

    public HomeController()
    {
    }

    public IActionResult Index()
    {       
        return View();
    }

    public IActionResult Privacy()
    {
        return View();
    }

    /// <summary>
    /// This can be access from /Home/ThrowHiddenException.
    /// 
    /// It demonstrates whether exception handling and logging in the H ASP.NET Core 
    /// application is working correctly. A log entry should be made.
    /// 
    /// THEX string is searchable in the logs.
    /// </summary>
    /// <returns></returns>
    public IActionResult ThrowHiddenException()
    {
        throw new Exception("THEX: Test exception handling and logging.");
    }

    [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
    public IActionResult Error()
    {
        return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
    }
}

Кто-нибудь сталкивался с этим раньше? Из того, что я могу сказать, это может быть вызвано тем, что страница хочет пройти аутентификацию, прежде чем к ней можно будет получить доступ, а это не то, чего я хотел бы для домашней страницы, которая приветствует пользователя на сайте.

Обновление1: Если я удаляю Login.cshtml, дом теперь работает, но мне, конечно, нужна страница входа.

Обновление 2: Считая, что это может быть проблема с аутентификацией, я смотрю на свои службы. Параметры ConfigureApplicationCookie и все выглядит хорошо. У меня есть LoginPath на всякий случай, но результаты те же.

Обновление 3: Снимки экрана установки sdk: Installed SDK version

VS cries

Env. Variables

Обновление 4: для чего это важно, в журналах я вижу это: [INF] Route matched with {page = "/Account/Login", area = "Identity", action = "", controller = ""}. Executing page /Account/Login

Все еще не уверен, где это происходит в коде. Так странно.

Ответы [ 2 ]

1 голос
/ 22 октября 2019

Я нашел проблему. Страница бритвы входа в систему была @page "/" вверху, и я думаю, что такой маршрут превосходит любую другую маршрутизацию, которая может происходить при запуске. Удаление «/» решило проблему. Я изменил мой на «логин».

Если у кого-то еще есть эта проблема, проверьте верхнюю часть своей страницы бритвы.

0 голосов
/ 22 октября 2019

Ваша проблема вызвана options.Conventions.AddPageRoute("/Identity/Account/Login", "");, который перенаправит https://localhost на /Identity/Account/Login.

Попробуйте закомментировать эту строку options.Conventions.AddPageRoute("/Identity/Account/Login", "");.

...