Передача HttpContext.Current.User.Identity в WCF - PullRequest
6 голосов
/ 11 марта 2012

Нужен небольшой совет (или, может быть, даже прямой ответ).

У меня есть веб-сайт MVC3. У меня также есть набор запущенных служб WCF (сейчас все в одной коробке).

То, что я пытаюсь сделать, - это аутентифицировать клиента (эта часть работает нормально), а затем передать этого аутентифицированного пользователя различным вызовам WCF.

На данный момент я подключил метод Application_AuthenticateRequest() в Global.Asax, который сводится к созданию нового GenericIdentity & GenericPrincipal, а затем присвоению этого принципала HttpContext.Current.User:

...
GenericIdentity identity = new GenericIdentity(userName);
GenericPrincipal principal = new GenericPrincipal(identity, null);
HttpContext.Current.User = principal;
...

И эта часть, кажется, тоже работает нормально.

Но когда я нажал на свой сервис, я полностью потерял установленного мной пользователя. Значения пустые или ложные.

Единственное, что я заметил, это то, что на стороне клиента объект HttpContext.Current.User.Identity имеет тип {System.Web.Security.FormsIdentity}, но в службе он имеет тип {System.Security.Principal.WindowsIdentity}.

Исходя из того, что я прочитал, звучит как простая модификация моего web.config, поэтому он может содержать aspNetCompatibilityEnabled="true", чтобы этого было достаточно. Но это не то, что я вижу. Так что либо я не все понимаю (очень хорошая возможность), либо я что-то напортачил (еще одна хорошая возможность).

Итак, мой вопрос. Возможно ли это вообще, и если да - мысли о том, чего мне не хватает? Я заметил, что некоторые другие опубликовали нечто подобное, но так и не получили определенного ответа (см. здесь и здесь ).

Любые предложения очень приветствуются.

1 Ответ

2 голосов
/ 11 марта 2012

Я не могу прямо ответить на ваш вопрос, но, надеюсь, поможет вам найти определенный ответ.

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

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

Факты:

  • Вам потребуется тот же механизм аутентификации.
  • Какой бы механизм вы ни использовали, он должен поддерживать тот 3-й прыжок, который вы хотите совершить (это означает, что вы можете использовать личность пользователя с 3-ей службой, фактически не имея учетных данных для повторной аутентификации).

Проблемы:

  • Если вы продолжите использовать проверку подлинности с помощью форм, то вам необходимо будет повторно пройти проверку подлинности с помощью службы WCF (и, конечно, предоставить учетные данные идентификации, , это может помочь). Мне трудно это сделать, если вы не сохраните пароль, который Пользователь использовал для аутентификации, что обычно является плохой идеей.
  • Если вы продолжите использовать проверку подлинности Windows для своего сайта, у вас возникнет проблема, если пользователь входит в систему из интрасети. Забавная вещь с Kerberos (Active Directory использует Kerberos) заключается в том, что он позволяет пользователю получать доступ к удаленным ресурсам без повторной аутентификации ... но этот маркер идентификации пользователя подходит только для 1 перехода. Хотя ваши службы WCF и MVC находятся на одном и том же сервере, он будет работать, но если вы в конечном итоге уберете свою службу WCF ... это граница 3-го блока ... 3-й прыжок, и билет Kerberos будет недостаточно хорош.

Итак ... не зная о ваших требованиях, я бы сначала предложил вам:

  • Забудьте об аутентификации на вашем слое WCF
  • Сделайте доступ к своей службе WCF приватным (отработайте свои навыки работы в сети ... межсетевые экраны и др.). Я бы начал с запуска WCF на отдельном веб-сайте IIS, который не прослушивает порт 80 (или 443), и убедился, что брандмауэр блокирует доступ к вашему новому порту WCF с IP-адресов вне вашей локальной сети (или, что еще лучше, за пределами вашего белого). список (пока локальный)).
  • Укажите идентификатор пользователя в качестве параметра каждого вызова WCF. Или, если вы чувствуете себя дико, изучите способы указания идентификатора пользователя через заголовки SOAP (если ваш WCF использует SOAP). Пользовательский заголовок тоже должен работать. Тогда вы будете доверять своему веб-сайту правильную проверку и аутентификацию пользователей перед предоставлением им доступа к вашим службам WCF.

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

...