.NET Core 5 Blazor Server - Loop to login page when required users to authenticate - Too many redirects

António Godinho 1 Reputation point
2021-06-07T08:10:35.757+00:00

I've been using Web Forms for many years. I'm trying to move to .Net Core Blazor/MVC. This was easy the old way...

I have an application that I need to required all users to be logged in. In theory, non authenticated should be redirected to the /Login page.

This is my settings on the Startup.cs file:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<UserDataContext>(
        x => x.UseSqlServer(Configuration.GetConnectionString("UsersConnection"
        )));

    services.AddRazorPages(options=>
        {
            options.Conventions.AuthorizeFolder("/");
            options.Conventions.AllowAnonymousToPage("/Login");
        });

    services.AddServerSideBlazor();
    services.AddSingleton<WeatherForecastService>();

    services.AddControllers();
    services
        .AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
        .AddCookie(options =>
        {
            options.LoginPath = "/login";
            options.LogoutPath = "/account/logout";
        });

    services.AddControllers(options => options.EnableEndpointRouting = false);

    services.Configure<ForwardedHeadersOptions>(options =>
    {
        options.ForwardedHeaders =
            ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
    });

    services.AddScoped<IUserLoginService, UserLoginService>();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseForwardedHeaders();

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseMvc();
    app.UseAuthentication();
    app.UseAuthorization();

    app.UseStatusCodePages(context =>
    {
        var response = context.HttpContext.Response;
        if (response.StatusCode == (int)HttpStatusCode.Unauthorized ||
            response.StatusCode == (int)HttpStatusCode.Forbidden)
            response.Redirect("/Login");
        return Task.CompletedTask;
    });

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
        endpoints.MapBlazorHub();
        endpoints.MapRazorPages();
        endpoints.MapFallbackToPage("/_Host");
    });
}

The Login component Pages/Login.razor has the AllowAnonymous:

@page "/login"
@page "/login/{ErrorMessage}"
@inject NavigationManager NavManager
@attribute [AllowAnonymous]
@layout LoginLayout

<div class="signin-logo tx-center tx-28 tx-bold tx-inverse"><span class="tx-normal">[</span> bracket <span class="tx-normal">]</span></div>
<div class="tx-center mg-b-60">MyISEC</div>
@if (ErrorMessage != null)
{
    <div class="text-danger">@ErrorMessage</div>
}
<form method="post" action="/account/login">
    <div class="form-group">
        <input type="text" name="username" class="form-control" placeholder="Utilizador">
    </div><!-- form-group -->
    <div class="form-group">
        <input type="password" name="password" class="form-control" placeholder="Enter your password">
    </div><!-- form-group -->
    <button type="submit" class="btn btn-info btn-block">Log In</button>
</form>

@code
{
    [Parameter]
    public string ErrorMessage { get; set; }
}

and the LoginController:

[AllowAnonymous]
public class LoginController : Controller
{
    private readonly IUserLoginService _loginService;

    public LoginController(IUserLoginService loginService)
    {
        _loginService = loginService;
    }

    [AllowAnonymous]
    [HttpPost("/account/login")]
    public async Task<IActionResult> Login(UserCredentials credentials)

But when the user goes to /Login, it ends up with too many redirects, the URL states exactly that:

https://localhost:44325/login?ReturnUrl=%2Flogin%3FReturnUrl%3D%252Flogin%253FReturnUrl%253D%25252Flogin%25253FReturnUrl%25253D%2525252Flogin%2525253FReturnUrl%2525253D%252525252Flogin%252525253FReturnUrl%252525253D%25252525252Flogin%25252525253FReturnUrl%25252525253D%2525252525252Flogin%25252525252...........

This means I have a loop here, but I can't seam to find where. What I am missing here?

Thanks.

Blazor
Blazor
A free and open-source web framework that enables developers to create web apps using C# and HTML being developed by Microsoft.
1,494 questions
{count} votes