문제

보안 WCF 서비스를 구현하고 있습니다.인증은 사용자 이름/비밀번호 또는 Windows 자격 증명을 사용하여 수행됩니다.서비스는 Windows 서비스 프로세스에서 호스팅됩니다.이제 구현하는 가장 좋은 방법을 찾으려고 노력 중입니다. 권한 부여 각 서비스 운영에 대해

예를 들어 다음 방법을 고려해보세요.

public EntityInfo GetEntityInfo(string entityId);

아시다시피 WCF에는 호출자/클라이언트가 전달한 보안 자격 증명을 검색할 수 있는 OperationContext 개체가 있습니다.지금,입증 메서드의 첫 번째 줄이 호출될 때 이미 완료되었을 것입니다.그러나 결정이 입력 데이터 자체에 따라 달라지는 경우 승인을 어떻게 구현합니까?예를 들어 위의 경우 '관리자' 사용자(권한 등이 데이터베이스에 저장되어 있음)는 엔터티 정보를 얻을 수 있고 다른 사용자는 허용되지 않아야 한다고 가정합니다.승인 확인을 어디에 두나요?

다음과 같이 메서드의 첫 번째 줄에 넣었다고 가정해 보겠습니다.

CheckAccessPermission(PermissionType.GetEntity, user, entityId) //user is pulled from the current OperationContext

이제 몇 가지 질문이 있습니다.

  1. 승인 확인 전에 또는 승인 확인 내부에서 엔터티 ID를 검증합니까(예: null/빈 값 확인 등)?즉, 모든 메소드에 인증 확인을 포함해야 한다면 이것이 좋은 패턴일까요?인수 검증 또는 승인 중 어느 것이 먼저 발생해야 합니까?

  2. 권한 부여 확인이 여기저기서 이루어지고 단위 테스트에 OperationContext가 없는 경우 WCF 서비스를 어떻게 단위 테스트합니까?(WCF 설정 없이 이 서비스 클래스 구현을 직접 테스트하려고 한다고 가정합니다.)

어떤 아이디어라도 있나요?

도움이 되었습니까?

해결책

질문 1의 경우 반드시 먼저 인증을 수행하십시오.가장 엄격한 보안을 유지하기 위해 인증 전에는 어떤 코드도(귀하의 제어 범위 내에서) 실행되어서는 안 됩니다.위의 Paul의 예는 훌륭합니다.

질문 2의 경우 구체적인 서비스 구현을 서브클래싱하여 이를 처리할 수 있습니다.위에서 언급한 추상 "CheckPermissions" 메서드를 사용하여 실제 비즈니스 논리 구현을 추상 클래스로 만듭니다.그런 다음 2개의 하위 클래스를 만듭니다. 하나는 WCF용이고 다른 하나는 true(또는 단위 테스트에서 수행하려는 모든 작업)를 반환하는 배포되지 않은 DLL에서 매우 격리되어 있습니다.

예(단, 동일한 파일이나 DLL에 있어서는 안 됩니다!):

public abstract class MyServiceImpl
{
    public void MyMethod(string entityId)
    {
        CheckPermissions(entityId);
        //move along...
    }
    protected abstract bool CheckPermissions(string entityId);
}

public class MyServiceUnitTest
{
    private bool CheckPermissions(string entityId)
    {
        return true;
    }
}

public class MyServiceMyAuth
{
    private bool CheckPermissions(string entityId)
    {
        //do some custom authentication
        return true;
    }
}

그런 다음 WCF 배포에서는 "MyServiceMyAuth" 클래스를 사용하고 다른 클래스에 대해 단위 테스트를 수행합니다.

다른 팁

질문 1의 경우 먼저 승인을 수행하는 것이 가장 좋습니다. 이렇게하면 유효성 검사 오류 메시지를 무단 사용자에게 다시 누출하지 않습니다.

BTW는 집에서 재배 된 인증 방법을 사용하는 대신 (체크 액세스 제공이란 무엇이라고 생각하는지) ASP.NET 역할 공급자에 대한 WCF의 기본 지원에 연결할 수 있습니다. 이 작업이 완료되면 OperationContext.current.servicesecurityContext.primaryIdentity.isinrole ()을 통해 인증을 수행합니다. 1 차 정체성은 iprincipal입니다.

질문 #2에 대해서는 종속성 주입을 사용하여 이 작업을 수행하고 다음과 같이 서비스 구현을 설정합니다.

class MyService : IMyService
{
    public MyService() : this(new UserAuthorization()) { }
    public MyService(IAuthorization auth) { _auth = auth; }

    private IAuthorization _auth;

    public EntityInfo GetEntityInfo(string entityId)
    {
            _auth.CheckAccessPermission(PermissionType.GetEntity, 
                    user, entityId);

            //Get the entity info
    }
}

IAuthorization은 사용자가 정의하는 인터페이스입니다.

서비스 유형을 직접 테스트할 것이기 때문에(즉, WCF 호스팅 프레임워크 내에서 실행하지 않고) 모든 호출을 허용하는 더미 IAuthorization 유형을 사용하도록 서비스를 설정하기만 하면 됩니다.그러나 더 나은 테스트는 IAuthorization을 모의하고 예상한 매개변수를 사용하여 언제 호출되는지 테스트하는 것입니다.이를 통해 메소드 자체와 함께 인증 메소드에 대한 호출이 유효한지 테스트할 수 있습니다.

인증을 자체 유형으로 분리하면 독립적으로 올바른지 더 쉽게 테스트할 수 있습니다.내 (제한적이긴 하지만) 경험에 따르면 DI "패턴"을 사용하면 유형의 문제를 훨씬 더 잘 분리하고 테스트 가능성을 높일 수 있을 뿐만 아니라 더 깔끔한 인터페이스를 얻을 수 있습니다(분명히 논쟁의 여지가 있음).

내가 선호하는 조롱 프레임워크는 다음과 같습니다. RhinoMocks 무료이고 매우 유창한 인터페이스를 가지고 있지만 다른 것들도 많이 있습니다.DI에 대해 더 자세히 알고 싶다면 여기 좋은 입문서와 .Net 프레임워크가 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top