2

プログラムとサービス内で追加情報が必要なため、カスタム プリンシパルと ID タイプ (ProdigyPrincipal/ProdigyIdentity) を使用しています。プログラムでは、プリンシパルと ID を設定します。WCF サービスと通信する場合、プリンシパルと ID が設定されますが、独自の型にキャストした後、プリンシパルと ID は null になります。

デバッグ モードと単体テスト モードでの実行には違いがあることに気付きました。デバッグ モードでは、プリンシパルと ID の型はWindowsPrincipalWindowsIdentityです。単体テスト モードでは、型は GenericPrincipal と GenericIdenity です。カスタム型にキャストする場合、どちらの場合も値は null です。

プリンシパル/ID の設定と取得は、Thread.CurrentPrincipalを介して行われます。バインディング セクションの App.configs で、セキュリティ モードが「トランスポート」に設定されています。

設定/プリンシパルと ID の取得に使用される関数:

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

カスタム プリンシパルと ID タイプをThreadから取得できない理由を知っている人はいますか?

敬具、ハンス

4

1 に答える 1

8

WCF には、 ServiceAuthorizationBehaviorを介して同じ目標を達成するためのより標準的な方法があります。

その PrincipalPermissionMode プロパティを "Custom" に設定すると、WCF ServiceSecurityContext でカスタムを使用IAuthorizationPolicyできるようにするカスタムを提供できます。IPrincipalDispatchRuntime は、この (カスタム) 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;
    }
}

これは、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]サービス内では、属性を介して宣言型セキュリティを利用できます。カスタムIPrincipalを から取得できます。 Thread.CurrentPrincipal(代わりに) からカスタム IIdentity を取得することもできますServiceSecurityContext.Current.PrimaryIdentity

問題が解決することを願っています。

于 2011-05-07T12:51:19.383 に答える