73

Я создаю веб-приложение с уровнем обслуживания. Уровень сервиса будет построен с использованием дизайна RESTful. Мысль заключается в том, что в будущем мы можем создавать другие приложения (iPhone, Android и т. Д.), Которые используют тот же уровень обслуживания, что и веб-приложение. Мой вопрос в том, как я могу внедрить логин? Я думаю, что у меня возникли проблемы с переходом от более традиционного глагольного дизайна к ресурсовому дизайну. Если бы я строил это с помощью SOAP, у меня, вероятно, был бы метод под названием «Вход». В REST у меня должен быть ресурс. Мне трудно понять, как я должен создать свой URI для входа. Должно ли оно быть что-то вроде этого:Как реализовать вход в веб-службу RESTful?

http://myservice/ {имя пользователя} р = {пароль}

EDIT: Передняя часть веб-приложение использует традиционные рамки ASP.NET для проверки подлинности. Однако в какой-то момент процесса аутентификации мне необходимо проверить предоставленные учетные данные. В традиционном веб-приложении я бы сделал поиск базы данных. Но в этом случае я вызываю службу вместо того, чтобы выполнять поиск базы данных. Поэтому мне нужно что-то в службе, которая будет проверять предоставленные учетные данные. Кроме проверки достоверности предоставленных учетных данных, мне, вероятно, также потребуется какая-то информация о пользователе после успешной аутентификации - такие вещи, как их полное имя, их идентификатор и т. Д. Надеюсь, это упростит вопрос.

Или я не думаю об этом правильно? Я чувствую, что мне трудно описать свой вопрос правильно.

Corey

ответ

55

Как отметил С. Лотт уже, у нас есть два сложенных вещей здесь: Логин и аутентификация

Аутентификация вне сферы здесь, как это широко обсуждается и существует общее согласие. Однако что нам на самом деле нужно, чтобы клиент успешно аутентифицировался против веб-службы RESTful? Правильно, какой-то токен, назовем его токеном доступа.

Клиент) Итак, все, что мне нужно, это токен доступа, но как получить такой ОТДЫХ?
Server) Почему бы просто не создать его?
Клиент) Как получается?
Server) Для меня токен доступа - это не что иное, как ресурс. Таким образом, я создам один для вас в обмен на ваше имя пользователя и пароль.

Таким образом, сервер может предлагать URL-адрес ресурса «/ accesstokens» для POSTing имени пользователя и пароля, возвращая ссылку на вновь созданный ресурс «/ accesstokens/{accesstoken}». В качестве альтернативы, вы возвращаете документ, содержащий доступ лексему и A HREF с ссылкой ресурса:

 
<access-token 
    id="{access token id goes here; e.g. GUID}" 
    href="/accesstokens/{id}" 
/> 

Скорее всего, вы не на самом деле создать доступ-маркер как subresource и, таким образом, не будет включать в себя его href в ответе.
Однако, если вы это сделаете, клиент может создать ссылку от своего имени или нет? Нет!
Помните, что действительно веб-службы RESTful связывают ресурсы вместе таким образом, чтобы клиент мог самостоятельно перемещаться без необходимости создавать какие-либо ссылки ресурсов.

Последний вопрос, который вы, вероятно, имеете, заключается в том, если вы должны ПОЧТИТЬ имя пользователя и пароль в виде HTML-формы или в качестве документа, например. XML или JSON - это зависит ... :-)

+3

Не совсем следуя за REST, но просто и заметно лучше других. Плюс поделился с хорошим юмором. –

+1

Патрик, вы предлагаете то же самое, что и этот ответ? http://stackoverflow.com/a/1135995/14731 – Gili

+0

Правильный код состояния 403, когда имя пользователя и/или пароль не совпадают? – sevteen

-4

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

Как я обычно справиться с этим является наличие Войти ресурс и передавая имя пользователя и пароль на строку параметров, в основном делает

GET на http://myservice/login?u= {имя пользователя} & р = {пароль}

Отклик некоторую сессию или строку auth, которая затем может быть передана другим API для проверки.

Альтернатива выполнению GET на ресурсе входа делает POST, REST пуристы, вероятно, сейчас не будут нравиться мне :) и передают в себя теги в теле. Ответ будет таким же.

+11

пароль? Обычный текстовый пароль?Как строка запроса? Вы действительно имели в виду это, или вы имеете в виду дайджест пароля? –

+0

Спасибо. В этом есть смысл. Вот следующий вопрос: для большого приложения вы могли бы создать один большой сервис RESTful для всего или разбить вещи на разные сервисы? Я думал о предоставлении услуги только для аутентификации, а затем о различных услугах для разных модулей моего приложения. Есть ли какие-либо причины, по которым вы бы или не сделали бы это так или иначе? –

+2

S. Lott: Это зависит от того, что вы пытаетесь сделать. Конечно, если вы можете сделать дайджест, то непременно. Иногда дайджест невозможен. Если единственный доступный вам вариант - отправка текстового пароля, пожалуйста, сделайте это через SSL, в этом случае лучше использовать POST, а не GET, чтобы браузер не помнил, что вы отправили. – Alex

22

Вы не «входите». Вы "аутентифицируете". Мир разницы.

У вас есть много альтернатив аутентификации.

HTTP Basic, Digest, NTLM and AWS S3 Authentication

  • HTTP Basic и проверка подлинности. Это использует заголовок HTTP_AUTHORIZATION. Это очень мило, очень просто. Но может привести к большому количеству трафика.

  • Аутентификация имени пользователя/подписи. Иногда называется аутентификацией «ID и KEY». Это может использовать строку запроса.

    ?username=this&signature=some-big-hex-digest

    Это то, что такие места, как использование Amazon. Имя пользователя - «id». «Ключ» - это дайджест, аналогичный тому, который используется для аутентификации HTTP Digest. Обе стороны должны договориться о том, чтобы дайджест продолжался.

  • Некоторая аутентификация на основе файлов cookie. Например, OpenAM может быть настроен как агент для аутентификации и предоставления файла cookie, который может использовать ваш веб-сервер RESTful. Сначала клиент будет аутентифицироваться, а затем предоставить cookie с каждым запросом RESTful.

+0

Возможно, мне нужно уточнить мой вопрос. Пользователи, которые посещают веб-сайт, не будут напрямую взаимодействовать с сервисом RESTful. Они будут взаимодействовать с веб-приложением. Поэтому, когда пользователь пытается войти в веб-приложение, веб-приложение сделает вызов веб-службы (используя код C#). Затем, основываясь на ответе веб-службы, код будет либо регистрировать их в веб-приложении, либо нет. Имеет ли это смысл? Я не уверен, будут ли предлагаемые вами методы аутентификации работать, поскольку браузер пользователя не взаимодействует напрямую с сервисом. –

+0

@Corey Burnett: Правильно. Пользователи не могут взаимодействовать с веб-сервисом RESTful. Верный. Веб-приложения вызывают веб-службы. Все эти методы специально разработаны так, что приложение C# делает запрос RESTful с надлежащими учетными данными и получает ответ. Веб-служба RESTful никогда не обрабатывает «логин», потому что у нее нет сеансов. Он может обрабатывать аутентификацию, соглашаясь с тем, что запрос действителен. У нас есть «фиктивный» запрос, который просто отвечает «200 OK», если учетные данные хороши. –

+2

@ S.Lott @Corey Пользователи абсолютно могут взаимодействовать с системами RESTful. Большинство статических веб-сайтов HTML являются RESTful «сервисами». –

0

Поскольку совсем немного изменился с 2011 года ...

Если вы открыты для использования 3-й инструмент партии, и слегка отклоняясь от REST немного для веб-интерфейс, рассмотрите http://shiro.apache.org.

Shiro в основном дает вам фильтр сервлетов, предназначенный для аутентификации, а также авторизацию. Вы можете использовать все методы входа, перечисленные в @ S.Lott, включая простую проверку подлинности на основе форм.

Отфильтруйте остальные URL-адреса, требующие аутентификации, и Сиро сделает все остальное.

В настоящее время я использую это в своем собственном проекте, и до сих пор он работал очень хорошо.

Вот что-то еще люди могут быть заинтересованы. https://github.com/PE-INTERNATIONAL/shiro-jersey#readme

1

Большой вопрос, корректна. Мне очень нравится ответ Патрика.Я использую что-то вроде

-/пользователей/{имя пользователя}/loginsession

С POST и GET обрабатывается. Поэтому я отправляю новый сеанс регистрации с учетными данными, и затем я могу просматривать текущий сеанс как ресурс через GET.

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

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

Редактировать

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

Другое решение заключается в потоке токена, OAuth или JWT или иначе, что означает, что «вход в систему» ​​уже произошел другим процессом, возможно, обычным пользовательским интерфейсом входа в браузере, который основан на форме POST.

Мой ответ предназначен для службы, которая находится за этим пользовательским интерфейсом, при условии, что вы хотите, чтобы логин и авторизация и управление пользователями размещались в службе REST, а не в коде MVC сайта. Это служба входа в систему.

Он также позволяет другим службам «входить в систему» ​​и получать истекающий токен вместо использования предварительно открытого ключа, а также тестовых скриптов в CLI или Postman.

+2

Передайте токен в заголовке, да. Передайте его как часть URL-адреса, нет. URL-адрес зашифрован при использовании HTTPS. Однако; URL-адрес также сохраняется в истории браузера и в журналах сервера. Там есть много веских причин, чтобы избежать передачи конфиденциальных данных в параметрах запроса URL. – Craig

0

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

Для вашего первого вопроса вы можете создать API Restfull. Учетные данные (имя пользователя и пароль) будут переданы на ваш сервисный уровень. Затем уровень сервиса проверяет эти учетные данные и предоставляет токен. Критические данные могут быть либо простым именем пользователя/паролем, либо могут быть сертификатами SSL. SSL-сертификаты используют протокол OAUTH и более безопасны.

Вы можете создать свой URI следующим образом: URI для запроса токена->http://myservice/some-directory/token? (Вы можете пройти Credentilals в этом URI для Token)

Чтобы использовать этот токен для доступа к ресурсам, вы можете добавить этот [Авторизация: Носитель (токен)] в свой http-заголовок.

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

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

Вы также можете выполнить следующие ссылки для более информационно http://www.codeproject.com/Articles/687647/Detailed-Tutorial-for-Building-ASP-NET-WebAPI-REST

http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api