У вас есть две различные проблемы: аутентификация зарегистрированного пользователя и подготовка новой учетной записи пользователя.
Аутентификация пользователя
Это простая часть.У вас есть несколько вариантов:
- HTTP-аутентификация ( basic или digest ).Basic - это шутка, поэтому в качестве серьезной альтернативы он оставляет только Digest.
- HTTP-аутентификация NTLM / Kerberos (иначе говоря, встроенная аутентификация Windows) является пуленепробиваемой, если ваши клиенты присоединяются к домену NT (маловероятно).
- SSL / TLS Взаимная аутентификация
- HTTP-аутентификация по формам.Не стоит упоминать.
- Базовая проверка подлинности или проверка подлинности с помощью форм по безопасному каналу ( HTTPS )
Таким образом, остаются реальные опции: дайджест, взаимная защита SSL или базовые / формыпо зашифрованному каналу.
Дайджест HTTP очень легко реализовать на стороне клиента, просто добавьте имя пользователя / пароль к CredentialCache
, используемому с WebRequest
и все готово.Повторно используйте экземпляр CredentialCache между вызовами, чтобы воспользоваться преимуществами предварительной аутентификации.К сожалению, на стороне сервера все не так радужно: дайджест-проверка подлинности поддерживается должным образом только при интеграции с AD, см. Настройка дайджест-проверки подлинности .
Взаимная проверка подлинности SSL / TLS поддерживается как клиентом, так и сервером, но, опять же, серверная сторона действительно поддерживает его только при интеграции с AD, а не в режиме реального времени (см. Настройка аутентификации сопоставления сертификата клиента ).
Этопочему я считаю, что единственными реалистичными вариантами для приложения, которое не предназначено для использования по VPN в корпоративной среде, является использование базовой аутентификации или проверки подлинности с помощью форм по безопасному каналу (HTTPS).Для Basic вы должны представить пароль в виде обычного текста и то же самое для форм (в его обычном неизмененном воплощении), поэтому клиент должен иметь доступ к паролю в виде открытого текста, и то же самое относится и к серверу.Один из способов хеширования не сработает, вам нужно правильное шифрование безопасного хранения.
Теперь верно, что вы можете «усовершенствовать» схему аутентификации форм, чтобы сделать довольно сложные вещи, в основном, создавая дайджест-эквивалент в обмене HTTP-формами, но я считаю, что это выходит за рамки этого обсуждения.И если вы решите пойти по этому пути, вы должны действительно знать, что вы делаете, или использовать хорошо зарекомендовавшее себя решение (я ничего не знаю).
Хранениепароль: Для Basic / Digest / Forms клиент не хранит пароль, так как пароль фактически предоставляется пользователем.Самое большее, пароль может быть сохранен, чтобы избежать повторного ввода, и это должно быть сделано, как любой специфический для пользователя секрет, хранящийся на клиенте, зашифрованный с помощью DPAPI через класс ProtectedData .На стороне сервера, если используется пользовательская таблица, пароли должны храниться как односторонний хэш.Для Basic и Form подойдет любая хеш-схема (желательно соленая).Но для дайджеста хэш должен быть хешем HA1 из схемы дайджеста: md5(username:realm:password)
, чтобы сервер мог завершить квитирование аутентификации.Хотя для этого требуется довольно инвазивное переписывание стандартных провайдеров членства, которые поставляются с ASP, это все еще мой рекомендуемый способ.
Подготовка пользователя
Это немногохитрее, потому что это предполагает установление первоначального доверия.Если вы просмотрите все схемы, упомянутые выше, вы увидите, что ни одна, кроме Basic / Forms поверх HTTPS, не может сделать это внутриполосно: любое другое решение требует первоначального развертывания учетной записи пользователя, настроенной внеполосными средствами (где внеполосные ссылки относятся к используемой схеме).Взаимный SSL требует предоставления сертификатов, NTLM / Kerberos требует подготовки пользователей AD, Digest требует предоставления пароля пользователя.Для Basic / Forms и Digest существует удобное «внеполосное» решение: безопасный канал HTTPS, на который отправляется форма для создания учетной записи.Для сертификатов SSL / TLS и для AD все сложнее.
OpenID / OAuth
Совершенно другой подход заключается в делегировании аутентификации. Используйте OpenID с провайдерами, такими как Google или Yahoo, и OAuth с провайдерами, такими как Facebook или Twitter. Это феноменально хорошо работает с веб-приложениями (сама StackOverflow использует такую схему, как вы могли заметить, OpenID, один год спустя ). Существуют библиотеки и поставщики интеграции, которые действительно делают это так просто, как 3 клика и одна строка кода, например JanRain .
Единственная проблема с OpenID и OpenAuth - это интерактивная схема. Это работает только в том случае, если пользователь активно участвует в процессе входа в систему / аутентификации и, следовательно, устраняет все автоматизированные решения. Если ваше приложение выполняет какие-либо фоновые операции (например, работает как служба) или использует идентификатор приложения для «телефона-дома» без участия пользователя, тогда OpenID / OAuth не работают.