.NET Core 5 Blazor Server - Loop to login page when required users to authenticate - Too many redirects
António Godinho
1
Reputation point
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.