简体   繁体   English

带有 Blazor 的 ASP.NET Core:无法弄清楚 cookie 身份验证

[英]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).我试图按照本教程( 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 身份验证的应用程序。 For IDE I am using VS 2019 Preview.对于 IDE,我使用的是 VS 2019 预览版。

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.作者使用较早版本的 Blazor,但我使用客户端项目而不是 App 来遵循教程,因为我认为它们做同样的事情,只是在不同版本的 Blazor 中调用不同。

Here is a link to repo with my result: https://github.com/SaintMSent/TestBlazorCookieAuth这是我的结果的回购链接: 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).如果我转到 localhost:port/login 页面,则会创建 cookie(我检查了 Chrome 开发工具)。 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如果我从 MainLayout 中删除 Login 组件,一切都会正常加载,所以我认为问题出在 Login.cshtml 中的 HttpContext 和 HttpContextAccessor

在此处输入图片说明

Here is what Login.cshtml looks like这是 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 { }
    }
}

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到客户端项目中的 Startup.cs,一切都在加载,但 _httpContextAccessor.HttpContext.User 始终为空

Try to do this: 尝试这样做:

Add the following to Blazor.Web.App.Startup.cs: 将以下内容添加到Blazor.Web.App.Startup.cs:

services.AddHttpContextAccessor();

You also need this in <component-name>.cshtml 您还需要在<component-name>.cshtml

@using Microsoft.AspNetCore.Http
@inject IHttpContextAccessor httpContextAccessor

Edit: You should also remove the following from your Server.Startup 编辑:您还应该从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>();

I solved it the strange way. 我以奇怪的方式解决了它。 I created a controller I named AuthController and added these methods to it 我创建了一个名为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;
        }
    }

And then I call the API from the client side and it works perfectly for me 然后我从客户端调用API,它对我来说非常有用

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM