2012-03-10 3 views
5

Ищете небольшой совет (или, может быть, даже прямой ответ).Передача HttpContext.Current.User.Identity в WCF

У меня есть сайт 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" может быть достаточно, чтобы сделать эту работу должным образом. Но это не то, что я вижу. Поэтому либо я не понимаю все (очень хорошая возможность), либо у меня что-то испортилось (еще одна хорошая возможность).

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

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

+0

Странно, что вы говорите, что видите «FormsIdentity», когда вы специально устанавливаете «GenericIdentity» в контексте текущего пользователя. Вы там перепутали? –

ответ

2

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

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

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

Факты:

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

Проблема:

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

Так что ... не зная ваши требования, я бы первым предложить Вам:

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

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