Han*_*euw 2 wcf multithreading identity principal
我们使用自定义主体和身份类型(ProdigyPrincipal/ProdigyIdentity),因为我们需要在我们的程序和服务中提供额外信息.在程序中,我们设置了主体和身份.与WCF服务通信时,将设置主体和标识,但在转换为我们自己的类型后,主体和标识为空.
我注意到在调试模式和单元测试模式下运行之间存在差异.在调试模式下,主体和标识的类型是WindowsPrincipal和WindowsIdentity类型.在单元测试模式下,类型是GenericPrincipal和GenericIdenity.在转换为自定义类型的两种情况下,值都为null.
设置和获取主体/身份是通过Thread.CurrentPrincipal完成的.在绑定部分的App.configs中,安全模式设置为"传输".
用于设置/获取主体和身份的已用函数:
protected static bool SetProdigyPrincipal()
{
#region require Thread.CurrentPrincipal should not be null
if (Thread.CurrentPrincipal == null) // OK
{
throw new InvalidOperationException("SetProdigyPrincipal(): Thread.CurrentPrincipal should not be null");
}
#endregion require Thread.CurrentPrincipal should not be null
var prodigyPrincipal = Thread.CurrentPrincipal as ProdigyPrincipal;
#region require prodigyPrincipal should not be null
if (prodigyPrincipal == null) // NOT OK
{
throw new InvalidOperationException("SetProdigyPrincipal(): prodigyPrincipal should not be null");
}
#endregion require prodigyPrincipal should not be null
// Get the Windows identity from the current principal
var prodigyIdentity = Thread.CurrentPrincipal.Identity as ProdigyIdentity;
#region require windowsIdentity should not be null
if (prodigyIdentity == null) // NOT OK
{
throw new InvalidOperationException("SetProdigyPrincipal(): prodigyIdentity should not be null");
}
#endregion require windowsIdentity should not be null
// Create new instance of Prodigy principal
var newProdigyPrincipal = new ProdigyPrincipal(prodigyIdentity);
#region require prodigyPrincipal should not be null
if (prodigyPrincipal == null)
{
throw new InvalidOperationException("SetProdigyPrincipal(): prodigyPrincipal should not be null");
}
#endregion require prodigyPrincipal should not be null
// Set the prodigy principal
var principalIsSet = ProdigyPrincipal.SetCurrentPrincipal(newProdigyPrincipal, ProdigyService.EnterpriseServiceBus);
// Return principal is set status
return principalIsSet;
}
Run Code Online (Sandbox Code Playgroud)
有谁知道为什么无法从Thread中检索自定义主体和身份类型?
亲切的,汉斯
WCF通过ServiceAuthorizationBehavior实现了同一目标的更标准方法.
如果将其PrincipalPermissionMode属性设置为"Custom",则它允许您提供自定义IAuthorizationPolicy,您可以通过该自定义IPrincipal为WCF ServiceSecurityContext提供自定义.DispatchRuntime会将此(您的自定义)IPrincipal分配给Thread.CurrentPrincipal - 这就是您所追求的,对吧?
这是IAuthorizationPolicy实现的示例:
public class DemoAuthorizationPolicy : IAuthorizationPolicy
{
private readonly string id = Guid.NewGuid().ToString();
public string Id { get { return this.id; } }
public ClaimSet Issuer { get { return ClaimSet.System; } }
public bool Evaluate(EvaluationContext context, ref object state)
{
// Here, create your custom principal
IIdentity customIdentity = new GenericIdentity("myUserName", "myCustomAuthenticationType");
IPrincipal customPrincipal = new GenericPrincipal(customIdentity, new[] { "user", "powerUser" });
// Set EvaluationContext properties
context.Properties["Identities"] = new List<IIdentity> { customIdentity };
context.Properties["Principal"] = customPrincipal;
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
这就是你在Web.config中声明ServiceAuthorizationBehavior的方法:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceAuthorization principalPermissionMode="Custom" >
<authorizationPolicies>
<add policyType="PrincipalPermissionModeDemo.DemoAuthorizationPolicy, YourAssemblyName"/>
</authorizationPolicies>
</serviceAuthorization>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
Run Code Online (Sandbox Code Playgroud)
里面您服务,您可以然后通过利用声明性安全[PrincipalPermission]属性,你可以自定义的IPrincipal从Thread.CurrentPrincipal,和(或者)你也可以自定义的IIdentity的ServiceSecurityContext.Current.PrimaryIdentity.
希望能解决你的问题!