방법: 서비스에 대한 사용자 지정 권한 부여 관리자 만들기
WCF(Windows Communication Foundation)의 ID 모델 인프라는 확장 가능한 클레임 기반 권한 부여 모델을 지원합니다. 클레임은 토큰에서 추출되어 사용자 지정 권한 부여 정책에 의해 선택적으로 처리된 다음,AuthorizationContext에 배치됩니다. 권한 부여 관리자는 AuthorizationContext에서 클레임을 검사하여 권한 부여 결정을 내립니다.
기본적으로 권한 부여는 ServiceAuthorizationManager 클래스에서 결정되지만, 사용자 지정 권한 부여 관리자를 만들어 이러한 결정을 재정의할 수 있습니다. 사용자 지정 권한 부여 관리자를 만들려면 ServiceAuthorizationManager에서 파생되는 클래스를 만든 다음 CheckAccessCore 메서드를 구현합니다. 권한 부여는 CheckAccessCore 메서드에서 결정되며, 액세스가 허용되면 true
를 반환하고 액세스가 거부되면 false
를 반환합니다.
권한 부여 결정이 메시지 본문 내용에 따라 달라지는 경우 CheckAccess 메서드를 사용합니다.
성능 문제 때문에 가능하다면 권한 부여 결정 시 메시지 본문에 액세스하지 않아도 되도록 애플리케이션을 다시 디자인해야 합니다.
서비스에 대한 사용자 지정 권한 부여 관리자는 코드 또는 구성을 통해 등록할 수 있습니다.
사용자 지정 권한 부여 관리자를 만들려면
ServiceAuthorizationManager 클래스에서 클래스를 파생시킵니다.
public class MyServiceAuthorizationManager : ServiceAuthorizationManager {
Public Class MyServiceAuthorizationManager Inherits ServiceAuthorizationManager
CheckAccessCore(OperationContext) 메서드를 재정의합니다.
OperationContext 메서드에 전달되는 CheckAccessCore(OperationContext)를 사용하여 권한 부여 결정을 내립니다.
다음 코드 예제에서는 권한 부여 결정을 내리기 위해 FindClaims(String, String) 메서드를 사용하여 사용자 지정 클레임
http://www.contoso.com/claims/allowedoperation
을 찾습니다.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
코드를 사용하여 사용자 지정 권한 부여 관리자를 등록하려면
사용자 지정 권한 부여 관리자의 인스턴스를 만들어 ServiceAuthorizationManager 속성에 할당합니다.
ServiceAuthorizationBehavior 속성을 사용하여 Authorization에 액세스할 수 있습니다.
다음 코드 예제에서는
MyServiceAuthorizationManager
사용자 지정 권한 부여 관리자를 등록합니다.// 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()
구성을 사용하여 사용자 지정 권한 부여 관리자를 등록하려면
서비스에 대한 구성 파일을 엽니다.
<behaviors>에 <serviceAuthorization>을 추가합니다.
<serviceAuthorization>에
serviceAuthorizationManagerType
특성을 추가하고 해당 값을 사용자 지정 권한 부여 관리자를 나타내는 형식으로 설정합니다.클라이언트와 서비스 간의 통신을 보안하는 바인딩을 추가합니다.
이 통신에 대해 선택된 바인딩에 따라 AuthorizationContext에 추가되는 클레임이 결정되고, 사용자 지정 권한 부여 관리자는 이 클레임을 사용하여 권한 부여 결정을 내립니다. 시스템 제공 바인딩에 대한 자세한 내용은 시스템 제공 바인딩을 참조하세요.
<service> 요소를 추가하여 서비스 엔드포인트에 동작을 연결하고
behaviorConfiguration
특성 값을 <behavior> 요소에 대한 이름 특성 값으로 설정합니다.서비스 엔드포인트 구성에 대한 자세한 내용은 방법: 구성에서 서비스 엔드포인트 만들기를 참조하세요.
다음 코드 예제에서는
Samples.MyServiceAuthorizationManager
사용자 지정 권한 부여 관리자를 등록합니다.<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>
Warning
serviceAuthorizationManagerType을 지정할 경우 문자열에 정규화된 형식 이름이 포함되어야 합니다. 콤마 및 형식이 정의된 어셈블리의 이름입니다. 어셈블리 이름을 지정하지 않을 경우 WCF는 System.ServiceModel.dll에서 형식 로드를 시도합니다.
예시
다음 코드 예제에서는 ServiceAuthorizationManager 메서드 재정의를 포함하는 CheckAccessCore 클래스의 기본 구현을 보여 줍니다. 예제 코드에서는 AuthorizationContext에서 사용자 지정 클레임을 검사하고 해당 사용자 지정 클레임의 리소스가 true
의 동작 값과 일치하면 OperationContext를 반환합니다. ServiceAuthorizationManager 클래스 구현에 대한 자세한 내용은 권한 부여 정책을 참조하세요.
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