Search code examples
c#asp.netasp.net-mvcasp.net-core

SignInManager.IsSignedIn(User) is always false in _Layout.cshtml


I created a sample web application with Identity in order to manage authentication.

But currently I am facing an issue in _Layout.cshtml, SignInManager.IsSignedIn(User) is always false (even if the user login is successful):

This is the _Layout.cshtml file


    @using Microsoft.AspNetCore.Identity
@inject SignInManager<IdentityUser> SignInManager
@inject UserManager<IdentityUser> UserManager

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - SampleWebApplication</title>
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
    <link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
    <link rel="stylesheet" href="~/SampleWebApplication.styles.css" asp-append-version="true" />
</head>
<body>
    <header>
        <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
            <div class="container">
                <a class="navbar-brand" asp-area="" asp-page="/Index">Sample Web Application</a>
                <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
                        aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
                <div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
                    @if (SignInManager.IsSignedIn(User))
                    {
                        <ul class="navbar-nav flex-grow-1">
                            <li class="nav-item">
                                <a class="nav-link text-dark" asp-area="" asp-page="/Index">Home</a>
                            </li>
                              <li class="nav-item">
                                <a class="nav-link text-dark" asp-area="" asp-page="/Privacy">Privacy</a>
                            </li>
                        </ul>
                         <ul class="navbar-nav d-flex justify-content-end">
                            <li class="nav-item">
                                <a class="btn btn-primary" asp-area="" asp-page="/Logout">Logout</a>
                            </li> 
                        </ul>
                    }
                    else
                    {
                         <ul class="navbar-nav d-flex justify-content-end flex-grow-1 ">
                            <li class="nav-item">
                                <a asp-page="/Login" class="btn btn-primary">Login</a>
                            </li>
                              <li class="nav-item">
                               <a asp-page="/Register" class="btn">Register</a>
                            </li>
                        </ul>
                    }
                </div>
            </div>
        </nav>
    </header>
    <div class="container">
        <main role="main" class="pb-3">
            @RenderBody()
        </main>
    </div>

    <footer class="border-top footer text-muted">
        <div class="container">
            &copy; 2024 - SampleWebApplication - <a asp-area="" asp-page="/Privacy">Privacy</a>
        </div>
    </footer>

    <script src="~/lib/jquery/dist/jquery.min.js"></script>
    <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
    <script src="~/js/site.js" asp-append-version="true"></script>

    @await RenderSectionAsync("Scripts", required: false)
</body>
</html>

This is Program.cs file

using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.SqlServer;
using SampleWebApplication.Model;

var builder = WebApplication.CreateBuilder(args);


var connectionString = builder.Configuration.GetConnectionString("AuthConnectionString") ?? throw new InvalidOperationException();

// Add services to the container.

builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();

builder.Services.AddIdentity<IdentityUser, IdentityRole>().AddEntityFrameworkStores<AuthDbContext>();

builder.Services.AddDbContext<AuthDbContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("AuthConnectionString")));


var app = builder.Build();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/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.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
app.UseAuthentication();

Could anyone please suggest where I am going wrong? Also I want SignInManager.IsSignedIn(User) to return true after a successful login.


Solution

  • The middleware components in the Startup.cs file needs to be configured in the correct sequence to handle authentication before authorization.

    In your Program.cs, the

    app.UseAuthorization();
    

    is registered before:

    app.UseAuthentication();
    

    which is not correct. It's essential to call the authentication middleware before the authorization middleware. Ensures user identities are established and associated with the request before any authorization checks are performed, as in your case is using in _Layout.cshtml.