简体   繁体   English

Blazor 服务器无法访问具有 [Authorize] 属性的控制器

[英]Blazor Server cant access controller with [Authorize] attribute

I'm pretty new at websites so this might be a bit naive.我对网站很陌生,所以这可能有点天真。 Starting with the basic Blazor Server ( blazorserver ) template with individual user accounts for authentication, I've added a DefaultController to my Blazor app by going to Project > Add Controller , and selecting an API controller with read/write actions.从带有用于身份验证的个人用户帐户的基本Blazor 服务器( blazorserver ) 模板开始,我通过转到“项目” >“添加控制器”并选择具有读/写操作的 API控制器,将DefaultController添加到我的 Blazor 应用程序。

I then added the NuGet package Microsoft.AspNetCore.Blazor.HttpClient and added to Startup.cs :然后我添加了 NuGet 包Microsoft.AspNetCore.Blazor.HttpClient并添加到Startup.cs

services.AddScoped<HttpClient>();

I also injected HttpClient and NavigationManager into the FetchData.razor page.我还将HttpClientNavigationManager注入了FetchData.razor页面。 I then added to my FetchData.razor page a button and function:然后我向我的FetchData.razor页面添加了一个按钮和功能:

<button @onclick="@TryIt">Try It</button>
private async Task TryIt()
{
    var x = await httpClient.GetJsonAsync<List<string>>($"{navigationManager.BaseUri}api/Default");
}

I run the site and click the Try It button and it works fine: I see the two items from the list.我运行该站点并单击“试用”按钮,它工作正常:我看到列表中的两个项目。 Great!伟大的!

I then add the [Authorize] attribute to the HttpGet() action in the controller:然后我将[Authorize]属性添加到控制器中的HttpGet()操作:

// GET: api/Default
[HttpGet]
[Authorize]
public IEnumerable<string> Get()
{
    return new string[] { "value1", "value2" };
}

When I run the site again and click Try It , no joy (Unhandled Exception).当我再次运行该站点并单击Try It 时,没有任何乐趣(未处理的异常)。 Okay, maybe I need to login?好的,也许我需要登录? Run the site, login (after getting the database created and a user registered) and click Try It .运行站点,登录(在创建数据库并注册用户后)并单击Try It Again, I get the scary exception in the console:同样,我在控制台中遇到了可怕的异常:

Microsoft.AspNetCore.Components.Server.Circuits.RemoteRenderer: Warning: Unhandled exception rendering component: '<' is an invalid start of a value. Path: $ | LineNumber: 0 | BytePositionInLine: 0.

System.Text.Json.JsonException: '<' is an invalid start of a value. Path: $ | LineNumber: 0 | BytePositionInLine: 0.
 ---> System.Text.Json.JsonReaderException: '<' is an invalid start of a value. LineNumber: 0 | BytePositionInLine: 0.
   at System.Text.Json.ThrowHelper.ThrowJsonReaderException(Utf8JsonReader& json, ExceptionResource resource, Byte nextByte, ReadOnlySpan`1 bytes)
   at System.Text.Json.Utf8JsonReader.ConsumeValue(Byte marker)
   at System.Text.Json.Utf8JsonReader.ReadFirstToken(Byte first)
   at System.Text.Json.Utf8JsonReader.ReadSingleSegment()
   at System.Text.Json.Utf8JsonReader.Read()
   at System.Text.Json.JsonSerializer.ReadCore(JsonSerializerOptions options, Utf8JsonReader& reader, ReadStack& readStack)
   --- End of inner exception stack trace ---
   at System.Text.Json.ThrowHelper.ReThrowWithPath(ReadStack& readStack, JsonReaderException ex)
   at System.Text.Json.JsonSerializer.ReadCore(JsonSerializerOptions options, Utf8JsonReader& reader, ReadStack& readStack)
   at System.Text.Json.JsonSerializer.ReadCore(Type returnType, JsonSerializerOptions options, Utf8JsonReader& reader)
   at System.Text.Json.JsonSerializer.Deserialize(String json, Type returnType, JsonSerializerOptions options)
   at System.Text.Json.JsonSerializer.Deserialize[TValue](String json, JsonSerializerOptions options)
   at Microsoft.AspNetCore.Components.HttpClientJsonExtensions.GetJsonAsync[T](HttpClient httpClient, String requestUri)
   at BlazorApp.Pages.FetchData.TryIt() in E:\DLS\Sandbox7\BlazorAppSolution\BlazorApp\Pages\FetchData.razor:line 57
   at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task)
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle)
Microsoft.AspNetCore.Components.Server.Circuits.CircuitHost: Error: Unhandled exception in circuit 'H-xRrymKJQEov3vkCpOcExCeuUA2S2b1e15y6QSjxvw'.

I've been reading that to do this I might need to add a token to the HTTP request, but I have no idea how to get the token.我一直在阅读要做到这一点,我可能需要向 HTTP 请求添加令牌,但我不知道如何获取令牌。 Am I on the right track?我在正确的轨道上吗? What do I need to add?我需要添加什么? What am I missing?我错过了什么?

As I'm really new to this, I could use as much guidance as you can give in as much detail as you can provide.由于我对此非常陌生,因此我可以使用尽可能多的指导,提供尽可能多的细节。

First off, the exception is raised because the JsonSerializer is not capable of deserializing the content passed to it.首先,引发异常是因为 JsonSerializer 无法反序列化传递给它的内容。 it expects to get JSON that can be deserialize to a List , but gets a message from the server reporting of an error that has occurred.它期望获得可以反序列化为List 的JSON,但会从服务器获取一条消息,报告已发生的错误。 This message is provided in the form of HTML.此消息以 HTML 的形式提供。

You shouldn't use Microsoft.AspNetCore.Blazor.HttpClient in Blazor Server App.您不应在 Blazor 服务器应用程序中使用 Microsoft.AspNetCore.Blazor.HttpClient。 It is intended for use in Blazor WebAssembly Apps.它旨在用于 Blazor WebAssembly 应用程序。 Use the IHttpClientFactory to employ the HttpClient service in your server-side Blazor.使用 IHttpClientFactory 在服务器端 Blazor 中使用 HttpClient 服务。

Using the template with individual user accounts for authentication means that your users are authenticated by Asp.Net Core Identity system (IdentityUI), including a database, models, etc. All the goodies that come with IdentityUI.使用带有个人用户帐户的模板进行身份验证意味着您的用户通过 Asp.Net 核心身份系统 (IdentityUI) 进行身份验证,包括数据库、模型等。 IdentityUI 附带的所有好东西。 But this is only related to authentication.但这仅与身份验证有关。

Now, if you want to access Web Api end points, and want to secure these end points by decorating them with the Authorize attribute, you need to use an authorization system, such as OpenID Connect, etc.现在,如果您想访问 Web Api 端点,并希望通过使用 Authorize 属性修饰它们来保护这些端点,则需要使用授权系统,例如 OpenID Connect 等。

For a start, I'd recommend you to use JWT Token authentication to issue JWT Tokens to authenticated users.首先,我建议您使用 JWT 令牌身份验证向经过身份验证的用户颁发 JWT 令牌。 You may dedicate a controller for the task of authenticating the user, creating a JWT token which contains various claims about the user.您可以将控制器专门用于验证用户的任务,创建包含有关用户的各种声明的 JWT 令牌。 This JWT token is created only once, after the user has been authenticated, and it is passed to the calling code (your Blazor Server App), which should store it in the local storage (JavaScript local storage).此 JWT 令牌仅在用户通过身份验证后创建一次,并将其传递给调用代码(您的 Blazor 服务器应用程序),该代码应将其存储在本地存储(JavaScript 本地存储)中。 Now, whenever you want to retrieve data for a given user from a secured Web Api end point, you should read the Jwt token from the local storage, and add it to the Authorization header of your HTTP request.现在,无论何时您想从安全的 Web Api 端点检索给定用户的数据,您都应该从本地存储中读取 Jwt 令牌,并将其添加到您的 HTTP 请求的 Authorization 标头中。 The following is a demonstration how to make an HTTP request passing the Jwt Token in the Authorization header.下面演示如何通过 Authorization 头中的 Jwt Token 进行 HTTP 请求。 Note: This is done using the package you've added, which is not recommended to be used with server-side Blazor.注意:这是使用您添加的包完成的,不建议将其与服务器端 Blazor 一起使用。 You may use it temporarily, but at the end of the day, you should shift to IHttpClientFactory.您可以暂时使用它,但在一天结束时,您应该转向 IHttpClientFactory。

@code {
User[] users;

protected override async Task OnInitializedAsync()
{
    var token = await TokenProvider.GetTokenAsync();
    users = await Http.GetJsonAsync<User[]>(
        "api/users",
        new AuthenticationHeaderValue("Bearer", token));
}

} }

Note: This subject is very comprehensive, and I'd suggest you use the docs to get the basic of it.注意:这个主题非常全面,我建议您使用文档来了解它的基础知识。 There are also answers by me and others regarding authentication and authorization from which you can learn a great deal.我和其他人也有关于身份验证和授权的答案,您可以从中学到很多东西。 It is also essential to learn to use the components and objects relating to authorization in Blazor.学习在 Blazor 中使用与授权相关的组件和对象也很重要。

Hope this helps...希望这可以帮助...

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

相关问题 Blazor @attribute [Authorize] 标签不起作用 - Blazor @attribute [Authorize] tag is not working HomeController上的Authorize属性强制在AllowAnonymous控制器上登录 - Authorize attribute on HomeController forces login on AllowAnonymous controller 通过代码给一个controller添加Authorize Attribute - Add Authorize Attribute to a controller through code 如何使用 Identity Server 授权 Blazor WebAssembly SPA 应用程序 - How to authorize a Blazor WebAssembly SPA app using Identity Server .NETCore2 如何在控制器中不设置授权属性的情况下填充用户 - .NETCore2 how to populate User without setting Authorize attribute in controller 当安全令牌位于cookie中而不是授权标头中时,在控制器上授权属性 - Authorize attribute on controller when security token is in cookie instead of authorization header 使用 WsFederation 授权属性从不执行带注释的 controller 操作 - Authorize attribute using WsFederation never executes annotated controller action 动态添加角色以授权ASP.NET 5中的控制器属性 - Dynamically add roles to authorize attribute for controller in ASP.NET 5 .Net核心授权角色从全局到控制器的属性继承 - .Net core Authorize attribute inheritance of roles from global to controller 使用 MVC controller 中的 [Authenticate] 属性使用会话授权用户? - Use [Authenticate] attribute in MVC controller using sessions to authorize users?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM