在WCF服务中使用自定义主体和身份的问题 [英] Problem using custom principal and identity with WCF services

查看:101
本文介绍了在WCF服务中使用自定义主体和身份的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们使用的是自定义主体和身份类型(ProdigyPrincipal/ProdigyIdentity),因为我们需要程序和服务中的其他信息.在程序中,我们设置了主体和身份.与WCF服务通信时,将设置主体和身份,但是在转换为我们自己的类型后,主体和身份将为null.

We are using a custom principal and identity type (ProdigyPrincipal/ProdigyIdentity) because we need extra information within our programs and services. In the program we set the principal and identity. When communicating with a WCF service the principal and identity are set, but after casting to our own type the principal and identity are null.

我注意到在Debug模式和Unit Test模式下运行是有区别的.在调试模式下,主体和身份的类型为 WindowsPrincipal WindowsIdentity .在单元测试模式下,类型为GenericPrincipal和GenericIdenity.在两种情况下,当都强制转换为自定义类型时,该值为null.

I noticed that there is a difference between running in Debug mode and Unit Test mode. In Debug mode the type of the principal and identity are of type WindowsPrincipal and WindowsIdentity. In Unit Test mode the types are GenericPrincipal and GenericIdenity. In both situations when casting to the custom type the value is null.

通过 Thread.CurrentPrincipal 完成主体/身份的设置和获取. 在绑定"部分的App.configs中,安全模式设置为传输".

Setting and getting of the principal/identity is done through Thread.CurrentPrincipal. In the App.configs in the binding section the security mode is set to 'Transport‘.

用于设置/获取主体和身份的功能:

Used function for settings/getting the principal and identity:

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

有人知道为什么不能从 Thread 中检索自定义主体和身份类型吗?

Does anyone know why the custom principal and identity type can not be retrieved from Thread?

亲切的问候,汉斯

推荐答案

WCF通过 ServiceAuthorizationBehavior 具有实现相同目标的更标准方法.

WCF has a more standard way of achieving the same goal, via a ServiceAuthorizationBehavior.

如果将其PrincipalPermissionMode属性设置为"Custom",则它允许您提供自定义IAuthorizationPolicy,通过它可以使自定义IPrincipal可用于WCF ServiceSecurityContext. DispatchRuntime会将这个(您自定义的)IPrincipal分配给Thread.CurrentPrincipal-这是您所追求的,对吧?

If you set its PrincipalPermissionMode property to "Custom", it allows you to provide a custom IAuthorizationPolicy via which you can make a custom IPrincipal available to the WCF ServiceSecurityContext. The DispatchRuntime will assign this (your custom) IPrincipal to Thread.CurrentPrincipal - which is what you're after, right?

这是一个示例IAuthorizationPolicy实现:

This is a sample IAuthorizationPolicy implementation:

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

这是在Web.config中声明ServiceAuthorizationBehavior的方式:

And this is how you declare the ServiceAuthorizationBehavior in the Web.config:

  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceAuthorization principalPermissionMode="Custom" >
            <authorizationPolicies>
              <add policyType="PrincipalPermissionModeDemo.DemoAuthorizationPolicy, YourAssemblyName"/>
            </authorizationPolicies>
          </serviceAuthorization>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

在服务内部,您可以通过[PrincipalPermission]属性利用声明式安全性,可以从Thread.CurrentPrincipal获取自定义 IPrincipal ,并且(或者)还可以获取自定义 ServiceSecurityContext.Current.PrimaryIdentity中的IIdentity .

Inside your service you can then leverage declarative security via the [PrincipalPermission] attribute, you can get the custom IPrincipal from Thread.CurrentPrincipal, and (alternatively) you can also get the custom IIdentity from ServiceSecurityContext.Current.PrimaryIdentity.

希望能解决您的问题!

这篇关于在WCF服务中使用自定义主体和身份的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆