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
Utwórz klasę z ServiceAuthorizationManager klasy .
public class MyServiceAuthorizationManager : ServiceAuthorizationManager {
Public Class MyServiceAuthorizationManager Inherits ServiceAuthorizationManager
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
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
Otwórz plik konfiguracji usługi.
Dodaj usługęAuthorization <>do< zachowań.>
Do parametru <serviceAuthorization> dodaj
serviceAuthorizationManagerType
atrybut i ustaw jego wartość na typ reprezentujący niestandardowego menedżera autoryzacji.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.
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.MyServiceAuthorizationManager
autoryzacji.<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