带有Blazor的ASP.NET Core:无法确定Cookie身份验证

时间:2019-03-20 18:28:40

标签: c# asp.net asp.net-core blazor razor-components

我试图按照本教程(http://lightswitchhelpwebsite.com/Blog/tabid/61/EntryId/4316/A-Demonstration-of-Simple-Server-side-Blazor-Cookie-Authentication.aspx)进行操作,以便能够使用ASP.NET Core 3.0和Blazor框架v.0.9.0(最新版本)对Cookie进行身份验证。对于IDE,我正在使用VS 2019预览版。

作者使用的是Blazor的早期版本,但我遵循的是使用Client项目而不是App的教程,因为我认为它们的作用相同,只是在不同版本的Blazor中调用的方式有所不同。

以下是我的搜索结果回购链接:https://github.com/SaintMSent/TestBlazorCookieAuth

问题是,它不起作用。如果我转到localhost:port / login页面,则会创建cookie(我检查了Chrome开发者工具)。而且,如果我转到注销页面,则将其删除,因此这部分很好。但是该应用程序的其他页面将无法加载。如果我从MainLayout中删除Login组件,那么一切都很好,所以我认为问题出在Login.cshtml中的HttpContext和HttpContextAccessor。

enter image description here

这是Login.cshtml的样子

@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 { }
    }
}

请帮我弄清楚这是怎么回事。希望我提供了足够的详细信息,谢谢。

更新:如果我添加此行

        services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();

到Client项目中的Startup.cs,所有内容都已加载,但是_httpContextAccessor.HttpContext.User始终为空

2 个答案:

答案 0 :(得分:0)

尝试执行以下操作:

将以下内容添加到Blazor.Web.App.Startup.cs:

services.AddHttpContextAccessor();

您还需要<component-name>.cshtml

@using Microsoft.AspNetCore.Http
@inject IHttpContextAccessor httpContextAccessor

编辑:您还应该从Server.Startup中删除以下内容

 // As I've said above, add this to your Client.Startup, and not to the Server.Startup, though at the end of the day it's the same pipeline.
  services.AddHttpContextAccessor();
  // I'm not sure what is this for. Remove it :)
  services.AddScoped<HttpContextAccessor>();
  // This is used with Http Client Factory, right now is not supported in client-side blazor; requires some configuration; and in any case an HttpClient object is automatically created for you. 
  services.AddHttpClient();
  // Once again, superfluous, the HttpClient created for you is Singleton
  services.AddScoped<HttpClient>();

答案 1 :(得分:0)

我以奇怪的方式解决了它。我创建了一个名为AuthController的控制器,并向其中添加了这些方法

    [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;
        }
    }

然后我从客户端调用API,它对我来说非常合适