2009-12-19 1 views
4

У меня есть служба WCF для каждого вызова, которая размещается в IIS (.svc). В конструкторе службы я установил Thread.CurrentPrincipal = HttpContext.Current.User согласно this article. В этом случае HttpContext.Current.User имеет тип Microsoft.IdentityModel.Claims.ClaimsPrincipal и имеет претензии, которые были отправлены обратно из моей пользовательской пассивной STS. неThread.CurrentPrincipal службы ASP.Net WCF отбрасывается некоторым перехватчиком в среде Federated (WIF)

Однако, как только я шаг в моей работе службы и изучить Thread.CurrentPrincipal, в то время как этот объект еще типа Microsoft.IdentityModel.Claims.ClaimsIdentity, сам объект уже не такой же, как HttpContext.Current.User (IsAuthenticated = ложь, AuthenticationType = "" и имя является недействительным на Thread.CurrentPrincipal.Identity), в то время как эти значения все еще заполнены правильно на HttpContext.Current.User. Это говорит мне, что что-то перехватывает вызов операции и неправильно меняет текущий принцип на какой-то общий, пустой, неаутентифицированный главный принцип.

Я проверил идентификатор потока в конструкторе, а также в работе, и это то же самое в обоих местах, и оценки Thread.CurrentPrincipal в ближайшем окне после назначения из HttpContext.Current.User показывает, что в конструкторе правильно задается тождество потоков, поэтому между конструктором и методом происходит определенная работа, и что-то меняет мой Thread.CurrentPrincipal.

Кто-нибудь знает, что это делает, и как я могу предотвратить предотвращение/исправление этого поведения?

ответ

3

При настройке службы для WIF федерации, вы звоните

FederatedServiceCredentials.ConfigureServiceHost(this); 

Часть того, что этот вызов делает, чтобы настроить пользовательский ServiceAuthorizationManager типа IdentityModelServiceAuthorizationManager на хосте службы. Этот диспетчер авторизации получает вызов между активацией (строительство) экземпляра и выполнением операции и перезаписывает Thread.CurrentPrincipal с экземпляром IClaimsPrincipal, но он, похоже, не понимает, что он работает в Режим совместимости ASP.NET, поэтому он не тянет принципала от HttpContext.Current.User.

я смог обойти эту проблему, выводя из IdentityModelServiceAuthorizationManager и перекрывая метод CheckAccess следующим образом:

public class CustomAuthorizationManager : IdentityModelServiceAuthorizationManager 
{ 
    public override bool CheckAccess(System.ServiceModel.OperationContext operationContext, ref System.ServiceModel.Channels.Message message) 
    { 
     var result = base.CheckAccess(operationContext, ref message); 

     var properties = operationContext.ServiceSecurityContext.AuthorizationContext.Properties; 
     properties["Principal"] = System.Web.HttpContext.Current.User; 

     return result; 
    } 
} 

Это тогда будет применяться к узлу службы следующим образом:

protected override void InitializeRuntime() 
{ 
    FederatedServiceCredentials.ConfigureServiceHost(this); 
    this.Authorization.ServiceAuthorizationManager = new CustomAuthorizationManager(); 
    base.InitializeRuntime(); 
} 

И теперь, когда я вхожу в свою служебную операцию, у меня есть правильный IClaimsPrincipal на Thread.CurrentPrincipal, поэтому декларативный PrincipalPermission теперь работает должным образом.

+0

Это решение работает, однако я не уверен, есть ли ошибка в существующем IdentityModelServiceAuthorizationManager - я чувствую, что он должен быть в состоянии сказать, что он работает в режиме совместимости ASP.NET, и поэтому должен иметь возможность основной из HttpContext.Current.User автоматически. Должен ли я сообщить об этом Microsoft как об ошибке, прежде чем они отправят Microsoft.IdentityModel 1.0.0.0? –

0

Я предполагаю, что ничто не перехватывает вызов. Либо CurrentPrincipal сбрасывается к тому моменту, когда вы его изучаете, либо вы находитесь в другом потоке.

Проверьте CurrentPrincipal сразу после его назначения, и вы увидите правильное значение.

1

Настройки переустановки для вызова FederatedServiceCredentials.ConfigureServiceHost (это);

как ниже в system.serviceModel добавить следующие

<extensions> 
     <behaviorExtensions> 
     <add name="federatedServiceHostConfiguration" type="Microsoft.IdentityModel.Configuration.ConfigureServiceHostBehaviorExtensionElement, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/> 
     </behaviorExtensions> 
    </extensions> 

под внутри добавить folowing линии

<behavior name="serviceBehavior"> 
      <federatedServiceHostConfiguration name="MyService" /> 
6

Я просто столкнулся подобной проблемой. Я устанавливаю свой пользовательский принцип в конструкторе моей службы WCF. Когда я покинул конструктор и ввел метод, который я назвал, thread.currentprincipal был переопределен пустым. Я решил это, добавив следующее поведение:

<serviceAuthorization principalPermissionMode="None"></serviceAuthorization> 

Это сработало для меня.

Смежные вопросы