Udostępnij za pośrednictwem


Instrukcje: Tworzenie menedżera autoryzacji niestandardowej dla usługi

Infrastruktura modelu tożsamości w programie Windows Communication Foundation (WCF) obsługuje rozszerzalny model autoryzacji oparty na oświadczeniach. Oświadczenia są wyodrębniane z tokenów i opcjonalnie przetwarzane przez niestandardowe zasady autoryzacji, a następnie umieszczane w obiekcie AuthorizationContext. Menedżer autoryzacji sprawdza oświadczenia w obiekcie AuthorizationContext , aby podejmować decyzje dotyczące autoryzacji.

Domyślnie decyzje dotyczące autoryzacji są podejmowane przez klasę ServiceAuthorizationManager , jednak te decyzje mogą zostać zastąpione przez utworzenie niestandardowego menedżera autoryzacji. Aby utworzyć niestandardowego menedżera autoryzacji, utwórz klasę, która pochodzi z ServiceAuthorizationManager metody i implementuje CheckAccessCore metodę. Decyzje dotyczące autoryzacji są podejmowane w metodzie, która zwraca true informację o udzieleniu CheckAccessCore dostępu i false odmowie dostępu.

Jeśli decyzja o autoryzacji zależy od zawartości treści wiadomości, użyj CheckAccess metody .

Ze względu na problemy z wydajnością, jeśli to możliwe, należy przeprojektować aplikację, aby decyzja o autoryzacji nie wymagała dostępu do treści komunikatu.

Rejestrację niestandardowego menedżera autoryzacji dla usługi można wykonać w kodzie lub konfiguracji.

Aby utworzyć niestandardowego menedżera autoryzacji

  1. Utwórz klasę z ServiceAuthorizationManager klasy .

    public class MyServiceAuthorizationManager : ServiceAuthorizationManager
    {
    
    
    Public Class MyServiceAuthorizationManager
        Inherits ServiceAuthorizationManager
    
    
  2. Zastąpij metodę CheckAccessCore(OperationContext) .

    Użyj metody przekazanej OperationContextCheckAccessCore(OperationContext) do metody , aby podejmować decyzje dotyczące autoryzacji.

    W poniższym przykładzie kodu użyto FindClaims(String, String) metody w celu znalezienia oświadczenia http://www.contoso.com/claims/allowedoperation niestandardowego w celu podjęcia decyzji o autoryzacji.

    protected override bool CheckAccessCore(OperationContext operationContext)
    {
      // Extract the action URI from the OperationContext. Match this against the claims
      // in the AuthorizationContext.
      string action = operationContext.RequestContext.RequestMessage.Headers.Action;
    
      // Iterate through the various claim sets in the AuthorizationContext.
      foreach(ClaimSet cs in operationContext.ServiceSecurityContext.AuthorizationContext.ClaimSets)
      {
        // Examine only those claim sets issued by System.
        if (cs.Issuer == ClaimSet.System)
        {
          // Iterate through claims of type "http://www.contoso.com/claims/allowedoperation".
            foreach (Claim c in cs.FindClaims("http://www.contoso.com/claims/allowedoperation", Rights.PossessProperty))
          {
            // If the Claim resource matches the action URI then return true to allow access.
            if (action == c.Resource.ToString())
              return true;
          }
        }
      }
    
      // If this point is reached, return false to deny access.
      return false;
    }
    
    Protected Overrides Function CheckAccessCore(ByVal operationContext As OperationContext) As Boolean
        ' Extract the action URI from the OperationContext. Match this against the claims.
        ' in the AuthorizationContext.
        Dim action As String = operationContext.RequestContext.RequestMessage.Headers.Action
    
        ' Iterate through the various claimsets in the AuthorizationContext.
        Dim cs As ClaimSet
        For Each cs In operationContext.ServiceSecurityContext.AuthorizationContext.ClaimSets
            ' Examine only those claim sets issued by System.
            If cs.Issuer Is ClaimSet.System Then
                ' Iterate through claims of type "http://www.contoso.com/claims/allowedoperation".
                Dim c As Claim
                For Each c In cs.FindClaims("http://www.contoso.com/claims/allowedoperation", _
                     Rights.PossessProperty)
                    ' If the Claim resource matches the action URI then return true to allow access.
                    If action = c.Resource.ToString() Then
                        Return True
                    End If
                Next c
            End If
        Next cs
        ' If this point is reached, return false to deny access.
        Return False
    
    End Function
    

Aby zarejestrować niestandardowego menedżera autoryzacji przy użyciu kodu

  1. Utwórz wystąpienie niestandardowego menedżera autoryzacji i przypisz je do ServiceAuthorizationManager właściwości .

    Dostęp do obiektu ServiceAuthorizationBehavior można uzyskać przy użyciu Authorization właściwości .

    Poniższy przykładowy kod rejestruje niestandardowego MyServiceAuthorizationManager menedżera autoryzacji.

    // Add a custom authorization manager to the service authorization behavior.
    serviceHost.Authorization.ServiceAuthorizationManager =
               new MyServiceAuthorizationManager();
    
    ' Add a custom authorization manager to the service authorization behavior.
    serviceHost.Authorization.ServiceAuthorizationManager = _
        New MyServiceAuthorizationManager()
    
    

Aby zarejestrować niestandardowego menedżera autoryzacji przy użyciu konfiguracji

  1. Otwórz plik konfiguracji usługi.

  2. Dodaj usługęAuthorization <>do< zachowań.>

    Do parametru <serviceAuthorization> dodaj serviceAuthorizationManagerType atrybut i ustaw jego wartość na typ reprezentujący niestandardowego menedżera autoryzacji.

  3. Dodaj powiązanie, które zabezpiecza komunikację między klientem a usługą.

    Powiązanie wybrane dla tej komunikacji określa oświadczenia dodawane do AuthorizationContextprogramu , które są używane przez niestandardowego menedżera autoryzacji do podejmowania decyzji dotyczących autoryzacji. Aby uzyskać więcej informacji na temat powiązań dostarczonych przez system, zobacz Powiązania dostarczone przez system.

  4. Skojarz zachowanie z punktem końcowym usługi, dodając element usługi> i ustawiając wartość atrybutu na wartość behaviorConfiguration atrybutu name dla <elementu zachowania>.<

    Aby uzyskać więcej informacji na temat konfigurowania punktu końcowego usługi, zobacz Instrukcje: tworzenie punktu końcowego usługi w konfiguracji.

    Poniższy przykładowy kod rejestruje niestandardowego menedżera Samples.MyServiceAuthorizationManagerautoryzacji.

    <configuration>
      <system.serviceModel>
        <services>
          <service
              name="Microsoft.ServiceModel.Samples.CalculatorService"
              behaviorConfiguration="CalculatorServiceBehavior">
            <host>
              <baseAddresses>
                <add baseAddress="http://localhost:8000/ServiceModelSamples/service"/>
              </baseAddresses>
            </host>
            <endpoint address=""
                      binding="wsHttpBinding_Calculator"
                      contract="Microsoft.ServiceModel.Samples.ICalculator" />
          </service>
        </services>
        <bindings>
          <WSHttpBinding>
           <binding name = "wsHttpBinding_Calculator">
             <security mode="Message">
               <message clientCredentialType="Windows"/>
             </security>
            </binding>
          </WSHttpBinding>
        </bindings>
        <behaviors>
          <serviceBehaviors>
            <behavior name="CalculatorServiceBehavior">
              <serviceAuthorization serviceAuthorizationManagerType="Samples.MyServiceAuthorizationManager,MyAssembly" />
             </behavior>
         </serviceBehaviors>
       </behaviors>
      </system.serviceModel>
    </configuration>
    

    Ostrzeżenie

    Należy pamiętać, że po określeniu parametru serviceAuthorizationManagerType ciąg musi zawierać w pełni kwalifikowaną nazwę typu. przecinek i nazwa zestawu, w którym zdefiniowano typ. Jeśli pozostawisz nazwę zestawu, program WCF podejmie próbę załadowania typu z System.ServiceModel.dll.

Przykład

Poniższy przykład kodu przedstawia podstawową implementację ServiceAuthorizationManager klasy, która obejmuje zastępowanie CheckAccessCore metody. Przykładowy kod sprawdza wartość AuthorizationContext oświadczenia niestandardowego i zwraca true wartość, gdy zasób dla tego oświadczenia niestandardowego pasuje do wartości akcji z OperationContext. Aby uzyskać bardziej kompletną implementację ServiceAuthorizationManager klasy, zobacz Zasady autoryzacji.

public class MyServiceAuthorizationManager : ServiceAuthorizationManager
{
  protected override bool CheckAccessCore(OperationContext operationContext)
  {
    // Extract the action URI from the OperationContext. Match this against the claims
    // in the AuthorizationContext.
    string action = operationContext.RequestContext.RequestMessage.Headers.Action;
  
    // Iterate through the various claim sets in the AuthorizationContext.
    foreach(ClaimSet cs in operationContext.ServiceSecurityContext.AuthorizationContext.ClaimSets)
    {
      // Examine only those claim sets issued by System.
      if (cs.Issuer == ClaimSet.System)
      {
        // Iterate through claims of type "http://www.contoso.com/claims/allowedoperation".
          foreach (Claim c in cs.FindClaims("http://www.contoso.com/claims/allowedoperation", Rights.PossessProperty))
        {
          // If the Claim resource matches the action URI then return true to allow access.
          if (action == c.Resource.ToString())
            return true;
        }
      }
    }
  
    // If this point is reached, return false to deny access.
    return false;
  }
}

Public Class MyServiceAuthorizationManager
    Inherits ServiceAuthorizationManager

    Protected Overrides Function CheckAccessCore(ByVal operationContext As OperationContext) As Boolean
        ' Extract the action URI from the OperationContext. Match this against the claims.
        ' in the AuthorizationContext.
        Dim action As String = operationContext.RequestContext.RequestMessage.Headers.Action

        ' Iterate through the various claimsets in the AuthorizationContext.
        Dim cs As ClaimSet
        For Each cs In operationContext.ServiceSecurityContext.AuthorizationContext.ClaimSets
            ' Examine only those claim sets issued by System.
            If cs.Issuer Is ClaimSet.System Then
                ' Iterate through claims of type "http://www.contoso.com/claims/allowedoperation".
                Dim c As Claim
                For Each c In cs.FindClaims("http://www.contoso.com/claims/allowedoperation", _
                     Rights.PossessProperty)
                    ' If the Claim resource matches the action URI then return true to allow access.
                    If action = c.Resource.ToString() Then
                        Return True
                    End If
                Next c
            End If
        Next cs
        ' If this point is reached, return false to deny access.
        Return False

    End Function
End Class

Zobacz też