ASP.Net Поток службы WCF.CurrentPrincipal выбрасывается каким-либо перехватчиком в федеративной среде (WIF).

StackOverflow https://stackoverflow.com/questions/1932424

  •  20-09-2019
  •  | 
  •  

Вопрос

У меня есть служба WCF для каждого вызова, которая размещается в IIS (.svc).В конструкторе сервиса я устанавливаю Нитки.CurrentPrincipal = HttpContext.Текущий.Пользователь согласно эта статья.В данном случае HttpContext.Текущий.Пользователь относится к типу Майкрософт.IdentityModel.Претензии.Исходная претензия и имеет претензии, которые были отправлены обратно из моего пользовательского пассивного STS.

Однако, как только я войду в свой сервис и изучу Нитки.Текущий главный, в то время как этот объект все еще имеет тип Майкрософт.IdentityModel.Претензии.Идентификатор претензии, сам объект больше не является тем же самым , что и HttpContext.Текущий.Пользователь (IsAuthenticated = false, AuthenticationType = "", а имя в потоке равно нулю.CurrentPrincipal.Идентификатор), тогда как все эти значения по-прежнему заполнены правильно на HttpContext.Текущий.Пользователь.Это говорит мне о том, что что-то перехватывает вызов операции и неправильно изменяет текущего участника на какой-то общий, пустой, не прошедший проверку подлинности участник утверждений.

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

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

Это было полезно?

Решение 2

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

FederatedServiceCredentials.ConfigureServiceHost(this);

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

Мне удалось обойти это поведение, выведя из IdentityModelServiceAuthorizationManager и преодоление Проверить доступ метод следующим образом:

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();
}

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

Другие советы

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

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

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

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

как показано ниже в 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>

в разделе "внутри" добавьте следующую строку

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top