Подтвердить что ты не робот

Рекомендации по аутентификации и авторизации в Angular без нарушения принципов RESTful?

Я прочитал немало SO-потоков об аутентификации и авторизации с REST и Angular, но я все еще не чувствую, что у меня отличное решение для того, что я надеюсь сделать. Для некоторого фона я планирую создать приложение в AngularJS, где я хочу поддержать:

  • Ограниченный доступ гостей
  • Роль-доступ к приложению после аутентификации
  • Аутентификация через API

Все вызовы API REST должны выполняться через SSL. Я бы хотел создать приложение без нарушения правил RESTful, а именно не сохранять состояние сеанса на сервере. Конечно, все, что делается с авторизацией на стороне клиента, должно быть усилено на стороне сервера. Поскольку нам нужно передать все состояние с каждым запросом, я знаю, что мне нужно передать какой-то токен, чтобы сервер базы данных, получающий запрос REST, мог аутентифицировать и разрешать вызов.

С учетом сказанного мой главный вопрос касается аутентификации - какие здесь лучшие практики? Кажется, здесь обсуждается множество разных подходов, вот только некоторые из них, которые я нашел:

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

Моя главная забота об Amazon AWS и статье Джорджа Риз, кажется, предполагает, что потребитель - это программа, а не конечный пользователь. Общий секрет может быть выдан программисту заранее, который затем может использовать его для кодирования вызовов здесь. Здесь не так - мне нужно вызвать API REST из приложения от имени пользователя.

Будет ли такой подход достаточным? Скажем, у меня есть ресурс сеанса:

POST/api/session

Создайте новый сеанс для пользователя

Чтобы создать сеанс, вам нужно выполнить POST объект JSON, содержащий "имя пользователя" и "пароль".

{
    "email" : "[email protected]",
    "password" : "password"
}

Пример скручивания

curl -v -X POST --data '{"username":"[email protected]","password":"password"}' "https://app.example.com/api/session" --header "Content-Type:application/json"

ответ

HTTP/1.1 201 Created {
    "session": {
        "id":"520138ccfa4634be08000000",
        "expires":"2014-03-20T17:56:28+0000"
    }
}

Коды состояния

  • 201 - Создан, установлен новый сеанс
  • 400 - Неправильный запрос, объект JSON недействителен или отсутствует требуемая информация.
  • 401 - Несанкционированный доступ, проверка электронной почты/паролей.
  • 403 - Доступ запрещен, отключена учетная запись или лицензия недействительна

Я оставляю детали HATEOAS для ясности. На бэкэнд будет создан новый ключ сеанса ограниченного времени, созданный и связанный с пользователем. В последующих запросах я мог передать это как часть заголовков HTTP:

Authorization: MyScheme 520138ccfa4634be08000000 

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

Если все это происходит через SSL, я оставляю дверь открытой для любых атак, против которых я должен защищаться? Вы можете попытаться угадать ключи сеанса и поместить их в заголовок, поэтому я полагаю, что я мог бы дополнительно добавить GUID пользователя к ключу сеанса, чтобы предотвратить атаки с использованием грубой силы.

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

4b9b3361

Ответ 1

Когда кто-то спрашивает об аутентификации REST, я откладываю на веб-службы Amazon и в основном предлагаю "сделать это". Зачем? Потому что, с точки зрения "мудрости толпы", AWS решает проблему, сильно используется, сильно анализируется и проверяется людьми, которые знают и заботятся гораздо больше, чем большинство, о том, что делает безопасный запрос, чем большинство. И безопасность - это хорошее место, чтобы "не изобретать велосипед". Что касается "плеч, чтобы стоять", вы можете сделать хуже, чем AWS.

Теперь AWS не использует метод токена, скорее использует безопасный хэш на основе разделяемых секретов и полезной нагрузки. Это, возможно, более сложная реализация (со всеми ее процессами нормализации и т.д.).

Но он работает.

Недостатком является то, что он требует, чтобы ваше приложение сохраняло секретный ключ для людей (т.е. пароль), а также требует, чтобы сервер имел доступ к этой простой текстовой версии пароля. Это обычно означает, что пароль хранится в зашифрованном виде, а затем дешифруется по мере необходимости. И это еще более усложняет управление ключами и другие вещи на стороне сервера и безопасном методе хэширования.

Самая большая проблема, конечно, с любой техникой прохождения токена - Man in the Middle attack и повторные атаки. SSL смягчает их, в основном, естественно.

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

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

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

Ответ 3

Этот вопрос SO делает хорошую работу по подведению моего понимания REST

Неужели сеансы действительно нарушают RESTfulness?

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

Я хотел бы знать, что вы думаете о создании службы RESTful, хотя, возможно, это не очень большая проблема.

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

Короче говоря, я считаю, что цель RESTful - хорошая цель, но чисто апатрид, конечно же, создает дополнительный уровень сложности, когда дело доходит до аутентификации и проверки авторизации.

До сих пор я начал создавать свои задние части с помощью REST, делая URI, которые имеют смысл и используют правильные HTTP-глаголы, но все же используют токен в сеансе для простоты проверки подлинности (если не использовать несколько серверов).

Я прочитал ссылки, которые вы опубликовали, и AngularJS, похоже, фокусируется только на клиенте и, похоже, явно не ссылается на сервер в этой статье, он ссылается на другой (я не Node пользователь так простите меня, если моя интерпретация здесь не так), но кажется, что сервер полагается на клиента, чтобы сказать, какой уровень авторизации у него есть, что явно не очень хорошая идея.