ASP.Net Поток службы WCF.CurrentPrincipal выбрасывается каким-либо перехватчиком в федеративной среде (WIF).
-
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 сразу после его назначения, и вы должны увидеть правильное значение.