Веб-API OWIN - Как проверять токен при каждом запросе

У меня два приложения

  1. Клиентское приложение, построенное на ASP.NET MVC
  2. Сервер аутентификации на основе Web API + OWIN

Запланировали аутентификацию следующим образом

  1. Для входа в систему клиентское приложение отправит запрос на сервер аутентификации с зарегистрированными учетными данными.
  2. Сервер аутентификации сгенерирует токен и отправит его обратно клиентскому приложению.
  3. Клиентское приложение будет хранить этот токен в локальном хранилище.
  4. для каждого последующего запроса клиентское приложение будет прикреплять токен, хранящийся в локальном хранилище в заголовке запроса.

ТЕПЕРЬ НА СЕРВЕРНОЙ СТОРОНЕ ПРИЛОЖЕНИЯ CLEINT МНЕ НУЖНО ПРОВЕРЯТЬ, ЧТО ТОКЕН ПРИХОДИТ С КАЖДЫМ ЗАПРОСОМ, НЕ УКАЗАННЫЙ.

  1. Пожалуйста, предложите мне, как проверять токен в каждом запросе, поскольку я не знаю ключ, который OWIN использовал для создания токена.
  2. Правильно писать код для проверки токена в клиентском приложении или он должен быть на сервере аутентификации.
  3. Я планирую перенести весь код управления пользователями, например, зарегистрировать пользователя, изменить пароль на сервер аутентификации, чтобы мы могли повторно использовать его для другого клиентского приложения - это правильная практика дизайна?

До сих пор я написал код ниже, чтобы просто создать POC.

========================= Конфигурация OWIN ========

    [assembly: OwinStartup(typeof(WebApi.App_Start.Startup))]
    namespace WebApi.App_Start
    {
        public class Startup
        {
            public void Configuration(IAppBuilder app)
            {
                HttpConfiguration config = new HttpConfiguration();

                ConfigureOAuth(app);

                WebApiConfig.Register(config);
                app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
                app.UseWebApi(config);
            }

            public void ConfigureOAuth(IAppBuilder app)
            {
                OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions()
                {
                    AllowInsecureHttp = false,
                    TokenEndpointPath = new PathString("/token"),
                    AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
                    Provider = new SimpleAuthorizationServerProvider(),

         };

         // Token Generation

                app.UseOAuthAuthorizationServer(OAuthServerOptions);
                app.UseOAuthBearerAuthentication(new 
 OAuthBearerAuthenticationOptions());

            }
        }
    }

==============================oAuth Provided========================

 public class SimpleAuthorizationServerProvider: OAuthAuthorizationServerProvider
    {
        public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
        {
            context.Validated(); 
        }

        public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
        {


            context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });

            using (AuthRepository _repo = new AuthRepository())
            {
                IdentityUser user =  _repo.FindUser(context.UserName, context.Password);

                if (user == null)
                {
                    context.SetError("invalid_grant", "The user name or password is incorrect.");
                    return;
                }
            }

            var identity = new ClaimsIdentity(context.Options.AuthenticationType);
            identity.AddClaim(new Claim("sub", context.UserName));
            identity.AddClaim(new Claim("role", "user"));

            context.Validated(identity);

        }
    }

Пожалуйста помоги,

Спасибо,

@Павел

Не используйте локальное хранилище для токенов аутентификации, это небезопасно. Лучше использовать куки. owasp.org/index.php/HTML5_Security_Cheat_Sheet#Local_Storage

Robbert Draaisma 28.07.2018 23:58
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
10
1
13 233
4

Ответы 4

Please suggest me how to validate token in each request as i don't know the key the OWIN has used to generate the token.

Ваша текущая настройка, если вы добавили app.UseOAuthBearerAuthentication() в конвейер owin, будет аутентифицировать пользователя с помощью токена-носителя, который передается при каждом запросе для вас. Текущего пользователя можно будет найти через HttpContext.Current.User.

Затем используйте атрибут Authorize, чтобы решить, какие пользователи авторизованы на определенных конечных точках. Вот пример, когда пользователям с ролью «пользователь» разрешен доступ

[Authorize(Roles = "user")]
public class ValuesController : ApiController
{
}

Is is right to write code to validate token on client app or it should be on authication server.

НЕТ, вы не проверяете токен в клиенте, если ваши учетные данные неверны, вы вообще не получите токен. Это все, что вам нужно знать. А также, почему вы должны проверять токен на клиенте?

I am planning to shift all user management code like register user, change password to authentication server so than we can re-use it for different client app- is it right design practice?

Повторное использование поставщика токенов - обычное дело. Зачем изобретать колесо для каждого приложения? Создайте один отличный продукт или используйте сторонний продукт и повторно используйте его в своих приложениях.

Спасибо за ответ @Marcus.

paul sim 02.08.2018 10:09

Да добавлено app.UseOAuthBearerAuthentication (). Я видел, пытаюсь ли я получить доступ к любым ограниченным ресурсам с того же сервера авторизации (localhost: 58386) с недопустимым токеном, сервер внутренне проверяет токен и не разрешает доступ к этому методу. Но мое клиентское приложение находится в другом домене (localhost: 57543). Я хочу использовать один и тот же сервер авторизации (localhost: 58386) для аутентификации и авторизации всех [Авторизованных] методов, определенных в моем клиентском приложении (localhost: 57543)

paul sim 02.08.2018 10:09

Мне не удалось найти конфигурации, которые требуются в клиентском приложении, чтобы указать клиентскому приложению использовать сервер авторизации (приложение веб-API) для аутентификации и авторизации. Пожалуйста помоги.

paul sim 02.08.2018 17:37

@paulsim Вам необходимо разрешить клиентскому приложению декодировать и читать токен, сгенерированный из API авторизации. Оба приложения должны использовать один и тот же ключ компьютера. Вот отличный блог, который описывает этот шаг за шагом bitoftech.net/2014/09/24/…. Np, Если этот ответ был какой-либо помощи, пожалуйста, проголосуйте / примите.

Marcus Höglund 02.08.2018 21:59

Один из способов убедиться, что токен не был подделан, - это подписать его с помощью пары асимметричных ключей. Identity Server использует этот подход, как показано здесь.

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

Используйте Веб-токены JSON (JWT) и претендует на личность, а не случайные токены, требующие отслеживания выпущенных токенов.

JWT похож на паспорт, выданный доверенным органом. Паспорт подписан / проштампован, и вы можете убедиться, что он был выдан этим доверенным органом и не был подделан. Это означает, что целостность утверждения о праве доступа, представленного в токене, может быть проверена без сохранения состояния где-либо. Единственная коммуникация, которая должна произойти между доверяющим приложением и центром, - это начальная (безопасная) загрузка открытого ключа органа (используется для подписи токенов).

Также рекомендуется использовать стандартную схему утверждений, например OpenID Connect (http://openid.net/specs/openid-connect-core-1_0.html#StandardClaims).

Хорошую книгу по этой теме, которая очень помогла мне разобраться во всех этих концепциях, можно найти здесь: Руководство по идентификации и контролю доступа на основе утверждений.

Если вы используете create, sendback, save в localStorage и все, что касается токена JWT, как правильные, вы должны знать, что в .Net есть много способов, которыми вы можете управлять по запросу.

Управление на стороне сервера:

  1. Если вы используете Web API Core, в ядре вы можете создать Middleware, который работает как конвейер во время выполнения, и вы можете указать контекст и проверить запрошенный токен для дополнительной проверки информации: Этот.

  2. Если вы используете Asp.net MVC, вы можете использовать ActionFilter в MVC (Asp.Net-Core также имеет более продвинутый ActionFilter), который проходит каждый запрос, и вы можете проверить каждый запрос thisng abount, для получения дополнительной информации проверьте: Этот.

ClientSide Conftolling:

  1. После этого вы даете токен после входа в систему со стороны сервера, вы должны сохранить данные в localstorage, чтобы ваш браузер проверял их по запросу, эти данные, их преимущество - это Expireation и все подобные проблемы в token, сохраните в localstorage, и вы и браузер можете использовать это для получения дополнительной информации проверьте: Этот.

Удачи.

Что касается №2, вы также можете использовать промежуточное ПО с использованием OWIN.

hastrb 10.10.2019 13:09

Другие вопросы по теме