Контроллер доступа Blazor Server с атрибутом [Authorize] - PullRequest
1 голос
/ 02 апреля 2020

Я довольно новичок на сайтах, так что это может быть немного наивно. Начиная с шаблона basi c Blazor Server (blazorserver) с отдельными учетными записями пользователей для аутентификации, я добавил DefaultController в свое приложение Blazor, перейдя к Project > Добавить контроллер и выбрать контроллер API с действиями чтения / записи.

Затем я добавил пакет NuGet Microsoft.AspNetCore.Blazor.HttpClient и добавил к Startup.cs:

services.AddScoped<HttpClient>();

Я также ввел HttpClient и NavigationManager на страницу FetchData.razor. Затем я добавил на свою FetchData.razor страницу кнопку и функцию:

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

Я запускаю сайт и нажимаю кнопку Try It , и она работает нормально: я вижу два предмета из списка. Отлично!

Затем я добавляю атрибут [Authorize] к действию HttpGet() в контроллере:

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

Когда я снова запускаю сайт и нажимаю Try It нет радости (необработанное исключение). Хорошо, может мне нужно войти? Запустите сайт, войдите (после создания базы данных и регистрации пользователя) и нажмите Try It . Я снова получаю страшное исключение в консоли:

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'.

Я читал, что для этого мне может понадобиться добавить токен в запрос HTTP, но я не знаю, как получить маркер. Я на правильном пути? Что мне нужно добавить? Чего мне не хватает?

Поскольку я действительно новичок в этом, я мог бы использовать как можно больше указаний, сколько вы можете дать.

1 Ответ

0 голосов
/ 03 апреля 2020

Прежде всего, возникает исключение, потому что JsonSerializer не способен десериализовать передаваемый ему контент. он ожидает получить JSON, который можно десериализовать в List , но получает от сервера сообщение об ошибке, которая произошла. Это сообщение предоставляется в виде HTML.

. Вы не должны использовать Microsoft.AspNetCore.Blazor.HttpClient в Blazor Server App. Он предназначен для использования в приложениях Blazor WebAssembly. Используйте IHttpClientFactory для использования службы HttpClient в вашем сервере Blazor.

Использование шаблона с индивидуальными учетными записями пользователей для аутентификации означает, что ваши пользователи аутентифицируются Asp. Net Базовая система идентификации (IdentityUI) , включая базу данных, модели и др. c. Все вкусности, которые идут с IdentityUI. Но это связано только с аутентификацией.

Теперь, если вы хотите получить доступ к конечным точкам Web Api и хотите защитить эти конечные точки, украсив их атрибутом Authorize, вам необходимо использовать систему авторизации, такую ​​как OpenID Connect, et c ,

Для начала я бы порекомендовал вам использовать аутентификацию токенов JWT для выдачи токенов JWT аутентифицированным пользователям. Вы можете выделить контроллер для аутентификации пользователя, создав токен JWT, который содержит различные утверждения о пользователе. Этот токен JWT создается только один раз после аутентификации пользователя и передается в вызывающий код (ваше приложение Blazor Server), который должен хранить его в локальном хранилище (JavaScript локальное хранилище). Теперь, когда вы хотите получить данные для данного пользователя из защищенной конечной точки Web Api, вы должны прочитать токен Jwt из локального хранилища и добавить его в заголовок Authorization вашего HTTP-запроса. Ниже приведена демонстрация того, как сделать HTTP-запрос, передавая токен Jwt в заголовке авторизации. Примечание. Это делается с помощью добавленного вами пакета, который не рекомендуется использовать с серверной программой Blazor. Вы можете использовать его временно, но в конце дня вам следует перейти на 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));
}

}

Примечание. Этот предмет очень всеобъемлющий, и я бы посоветовал вам используйте документы, чтобы получить основы c. Есть также ответы от меня и других относительно аутентификации и авторизации, из которых вы можете многому научиться. Также важно научиться использовать компоненты и объекты, относящиеся к авторизации в Blazor.

Надеюсь, это поможет ...

...