Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 在WCF服务中使用自定义主体和标识时出现问题_Multithreading_Wcf_Identity_Principal - Fatal编程技术网

Multithreading 在WCF服务中使用自定义主体和标识时出现问题

Multithreading 在WCF服务中使用自定义主体和标识时出现问题,multithreading,wcf,identity,principal,Multithreading,Wcf,Identity,Principal,我们使用自定义主体和身份类型(ProdigyPrincipal/ProdigyIdentity),因为我们需要在我们的计划和服务中提供额外的信息。在程序中,我们设置了主体和标识。当与WCF服务通信时,会设置主体和标识,但在转换为我们自己的类型后,主体和标识为null 我注意到在调试模式和单元测试模式下运行是有区别的。在调试模式下,主体和标识的类型为WindowsPrincipal和WindowsIdentity。在单元测试模式中,类型是GenericPrincipal和GenericUnity。

我们使用自定义主体和身份类型(ProdigyPrincipal/ProdigyIdentity),因为我们需要在我们的计划和服务中提供额外的信息。在程序中,我们设置了主体和标识。当与WCF服务通信时,会设置主体和标识,但在转换为我们自己的类型后,主体和标识为null

我注意到在调试模式和单元测试模式下运行是有区别的。在调试模式下,主体和标识的类型为WindowsPrincipal和WindowsIdentity。在单元测试模式中,类型是GenericPrincipal和GenericUnity。在这两种情况下,当强制转换为自定义类型时,值都为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;
  }
有人知道为什么不能从线程中检索自定义主体和标识类型吗


出于善意,汉斯

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,我会。。。。