Аутентификация Blazor JWT - PullRequest
1 голос
/ 16 июня 2020

Я пытаюсь найти правильный способ реализации аутентификации JWT с помощью Blazor (WASM). После просмотра документации я получил представление о том, как работают встроенные компоненты, но все же вся картина для меня не ясна. Итак, в моем сценарии у меня есть сервер API, который будет использоваться, сервер API может выдавать токены JWT, и их можно использовать для аутентификации на конечных точках, где это необходимо.

Итак, прямо сейчас я пытаюсь выяснить, правильная роль для каждого компонента. Для начала у нас есть AuthenticationStateProvider, поскольку я понимаю, что этот компонент отвечает за получение токена JWT либо с сервера, либо если он хранится локально, также он может обрабатывать ссылку на токен sh при необходимости?

Теперь, когда я буду я буду использовать типизированные HTTP-клиенты, я буду использовать IHttpClientFactory, вместе с этим у меня будет AuthorizationMessageHandler для прикрепления токенов к желаемым экземплярам HTTP-клиента. реализация по умолчанию будет вызываться после создания HTTP-клиента и подготовки HTTP-запроса. Неясно, как этот IAccessTokenProvider получит токен. Итак, вопрос в том, должен ли я создавать свою собственную реализацию IAccessTokenProvider, и если да, то как она должна обрабатывать токены. Как я уже сказал, я не буду использовать никаких встроенных провайдеров аутентификации и вместо этого буду иметь свою собственную систему аутентификации JWT.

Спасибо.

1 Ответ

2 голосов
/ 16 июня 2020

Первые три абзаца очень четкие и правильные. Вот как вы должны это делать. Я могу опубликовать здесь фрагмент кода, чтобы продемонстрировать, как это делается на практике ...

У меня все разваливается, когда я пытаюсь разобраться с IAccessTokenProvider,

Неудивительно ... IAccessTokenProvider здесь не актуален. IAccessTokenProvider - это поставщик токенов, используемый в новой системе аутентификации токенов JWT для приложения WebAssembly Blazor. Но если вы хотите реализовать аутентификацию JWT самостоятельно, вы должны сделать это, как вы описали в первых трех абзацах ... что я могу резюмировать следующим образом:

  • Когда пользователь делает первый доступ к защищенной конечной точке веб-API, и он не прошел проверку подлинности (или не зарегистрирован), он перенаправлен на соответствующие страницы, введите свои учетные данные и т. д. c, которые вы передаете конечной точке веб-API, предназначенной для проверки подлинности пользователя (зарегистрируйтесь, если необходимо , et c.), после чего вызываемый метод действия создает токен JWT и отправляет его обратно в приложение WebAssembly Blazor, работающее в браузере. Вы должны хранить токен JWT (возможно, в локальном хранилище) и получать его всякий раз, когда вы выполняете HTTP-вызовы (добавление токена JWT в заголовки запроса).

Вышеописанный процесс также включает реализация объекта AuthenticationStateProvider, который обновляется с помощью состояния аутентификации и уведомляет подписчиков, таких как CascadingAuthenticationState, об изменении состояния аутентификации, в конце которого другие компоненты и объекты адаптируются к новой ситуации ... вы знаете, повторный рендеринг и т. д. c.

Итак, вы видите, вы получили токен JWT от своего веб-API, сохранили его в локальном хранилище, прочитали его и использовали. Чтение токена Jwt из вашего локального магазина и его анализ в значительной степени - это то, что делает IAccessTokenProvider, но в новой системе аутентификации, и, поскольку вы не используете эту систему, IAccessTokenProvider не имеет значения.

А как насчет автоматизации? c Внедрение токена в заголовки HTTP-клиента, могу ли я или должен по-прежнему исследовать пользовательский AuthorizationMessageHandler, иначе этот компонент не будет использоваться без IAccessTokenProvider?

Вы можете добавить свой Токен Jwt для каждого HTTP-вызова, как показано ниже:

    @code {
    Customer[] customers;

    protected override async Task OnInitializedAsync()
    {
        // Read the token from the local storage
        var token = await TokenProvider.GetTokenAsync();
        customers = await Http.GetFromJsonAsync<Customer[]>(
            "api/customers",
            new AuthenticationHeaderValue("Bearer", token));
    }
}

, что совершенно нормально. Но, конечно, вы можете создать собственный DelegatingHandler по образцу AuthorizationMessageHandler или, что еще лучше, BaseAddressAuthorizationMessageHandler, поскольку вы собираетесь использовать IHttpClientFactory для предоставления службы HttpClient. Попробуйте сначала попытаться использовать их без каких-либо изменений, а если это нецелесообразно, просто имитируйте их функциональность.

Последнее, что меня беспокоит, это реализация получения токена доступа и его локального хранения. На данный момент лучший подход, который я могу придумать, - это иметь глобальную службу аутентификации, эта служба обеспечит функциональность получения токена, его обновления, сохранения et c. И IAccessTokenProvider, и AuthenticationStateProvider будут использовать его при запросе токена, а также будут получать уведомления при изменении состояния аутентификации, например, при входе или выходе пользователя.

Perfect ... Примечание. AuthenticationStateProvider должен быть уведомлен об изменении статуса токена Jwt. Например, когда вы получаете новый токен от конечной точки Web Api, ваш код должен добавить его в локальное хранилище, а затем уведомить CUSTOM AuthenticationStateProvider об изменении. Ваш код также должен уведомить AuthenticationStateProvider, если вы удалите токен Jwt, чтобы ваш пользовательский интерфейс отразил эти изменения, et c.

Удачи.

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

...