IntegerOverlord
IntegerOverlord

Reputation: 1637

ASP.NET Core with Blazor: Cannot figure out cookie authentification

I tried to follow this tutorial (http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/4316/A-Demonstration-of-Simple-Server-side-Blazor-Cookie-Authentication.aspx) to be able to make an app with cookie authentification with ASP.NET Core 3.0 and Blazor framework v.0.9.0 (the latest version). For IDE I am using VS 2019 Preview.

Author uses earlier version of Blazor, but I followed the tutorial using Client project instead of App, since they do the same thing, I think, just called differently in different version of Blazor.

Here is a link to repo with my result: https://github.com/SaintMSent/TestBlazorCookieAuth

The problem is, it does not work. If I go to localhost:port/login page, cookie is created (I checked Chrome dev tools). And if I go to logout page, it is removed, so this part is fine. But other pages of the app won't load. If I remove Login component from MainLayout, everything is loading fine, so I think the problem is with HttpContext and HttpContextAccessor in Login.cshtml

enter image description here

Here is what Login.cshtml looks like

@using System.Security.Claims
@using Microsoft.AspNetCore.Http
@page "/login"
@inject IHttpContextAccessor _httpContextAccessor
@inject HttpClient Http
@if (User.Identity.Name != null)
{
    <b>You are logged in as: @User.Identity.Name</b> 
    <a class="ml-md-auto btn btn-primary" 
       href="/logout?returnUrl=/" 
       target="_top">Logout</a>
}
else
{
    <a class="ml-md-auto btn btn-primary" 
       href="/login?returnUrl=/" 
       target="_top">Login</a>
}
@functions {
    private ClaimsPrincipal User;
    protected override void OnInit()
    {
        base.OnInit();
        try
        {
    // Set the user to determine if they are logged in
            User = _httpContextAccessor.HttpContext.User;
        }
        catch { }
    }
}

Please, help me to figure out what is going on here. I hope I have provided enough details, thanks.

UPDATE: If I add this line

        services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();

to Startup.cs in Client project, everything is loading, but _httpContextAccessor.HttpContext.User is always null

Upvotes: 4

Views: 3842

Answers (1)

IntegerOverlord
IntegerOverlord

Reputation: 1637

I solved it the strange way. I created a controller I named AuthController and added these methods to it

    [Route("api/[controller]")]
    public class AuthController : Controller
    {
        [HttpGet]
        [Route("getlogin")]
        public string GetLogin()
        {
            if (User.Identity.IsAuthenticated)
            {
                return $"{User.Identity.Name}";
            }

            return string.Empty;
        }

        [HttpGet]
        [Route("getrole")]
        public string GetRole()
        {
            if (User.Identity.IsAuthenticated)
            {
                if (User.IsInRole("Admin"))
                {
                    return "Admin";
                }

                return "User";
            }

            return string.Empty;
        }
    }

And then I call the API from the client side and it works perfectly for me

Upvotes: 2

Related Questions