Multithreading 在WCF服务中使用自定义主体和标识时出现问题
我们使用自定义主体和身份类型(ProdigyPrincipal/ProdigyIdentity),因为我们需要在我们的计划和服务中提供额外的信息。在程序中,我们设置了主体和标识。当与WCF服务通信时,会设置主体和标识,但在转换为我们自己的类型后,主体和标识为null 我注意到在调试模式和单元测试模式下运行是有区别的。在调试模式下,主体和标识的类型为WindowsPrincipal和WindowsIdentity。在单元测试模式中,类型是GenericPrincipal和GenericUnity。在这两种情况下,当强制转换为自定义类型时,值都为null 主体/标识的设置和获取通过Thread.CurrentPrincipal完成。 在绑定部分的App.configs中,安全模式设置为“传输” 用于设置/获取主体和标识的功能:Multithreading 在WCF服务中使用自定义主体和标识时出现问题,multithreading,wcf,identity,principal,Multithreading,Wcf,Identity,Principal,我们使用自定义主体和身份类型(ProdigyPrincipal/ProdigyIdentity),因为我们需要在我们的计划和服务中提供额外的信息。在程序中,我们设置了主体和标识。当与WCF服务通信时,会设置主体和标识,但在转换为我们自己的类型后,主体和标识为null 我注意到在调试模式和单元测试模式下运行是有区别的。在调试模式下,主体和标识的类型为WindowsPrincipal和WindowsIdentity。在单元测试模式中,类型是GenericPrincipal和GenericUnity。
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;
}
有人知道为什么不能从线程中检索自定义主体和标识类型吗
出于善意,汉斯WCF通过一种服务授权行为有一种更标准的方式来实现相同的目标 如果将其PrincipalPermissionMode属性设置为“Custom”,则允许您提供一个自定义
IAAuthorizationPolicy
,通过该策略,您可以使自定义IPPrincipal
可用于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;
}
}
公共类DemoAuthorizationPolicy:IAAuthorizationPolicy
{
私有只读字符串id=Guid.NewGuid().ToString();
公共字符串Id{get{返回this.Id;}}
公共索赔集颁发者{get{return ClaimSet.System;}}
public bool Evaluate(EvaluationContext,ref对象状态)
{
//在这里,创建您的自定义主体
IIdentity customIdentity=新的GenericEntity(“myUserName”、“myCustomAuthenticationType”);
IPrincipal customPrincipal=新的GenericPrincipal(customIdentity,新[]{“用户”,“超级用户”});
//设置EvaluationContext属性
context.Properties[“Identity”]=新列表{customIdentity};
context.Properties[“Principal”]=customPrincipal;
返回true;
}
}
以下是您在Web.config中声明ServiceAuthorizationBehavior的方式:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceAuthorization principalPermissionMode="Custom" >
<authorizationPolicies>
<add policyType="PrincipalPermissionModeDemo.DemoAuthorizationPolicy, YourAssemblyName"/>
</authorizationPolicies>
</serviceAuthorization>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
然后,在服务内部,您可以通过[PrincipalPermission]
属性利用声明式安全性,您可以从线程.CurrentPrincipal
获取自定义IPrincipal,并且(或者)您还可以从服务安全上下文.Current.primaryidential
获取自定义IIdential
希望能解决你的问题 很好的调用-我知道context.Properties[“Principal”]是设置Thread.CurrentPrincipal的机制,但直到我在EvaluationContext上使用DotPeek,我才知道该上下文。Properties[“Identity”]是设置ServiceSecurityContext.Current.PrimaryIdentity的快捷方式。。。如果我能扔掉WCF,我会。。。。