WCF Service authorization patterns

后端 未结 3 500
名媛妹妹
名媛妹妹 2020-12-31 20:07

I\'m implementing a secure WCF service. Authentication is done using username / password or Windows credentials. The service is hosted in a Windows Service process. Now, I\'

相关标签:
3条回答
  • 2020-12-31 20:39

    For question 1, absolutely do authorization first. No code (within your control) should execute before authorization to maintain the tightest security. Paul's example above is excellent.

    For question 2, you could handle this by subclassing your concrete service implementation. Make the true business logic implementation an abstract class with an abstract "CheckPermissions" method as you mention above. Then create 2 subclasses, one for WCF use, and one (very isolated in a non deployed DLL) which returns true (or whatever you'd like it to do in your unit testing).

    Example (note, these shouldn't be in the same file or even DLL though!):

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

    Then your WCF deployment uses the class "MyServiceMyAuth", and you do your unit testing against the other.

    0 讨论(0)
  • 2020-12-31 20:39

    About question #2, I would do this using Dependency Injection and set up your service implementation something like this:

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

    Note that IAuthorization is an interface that you would define.

    Because you are going to be testing the service type directly (that is, without running it inside the WCF hosting framework) you simply set up your service to use a dummy IAuthorization type that allows all calls. However, an even BETTER test is to mock the IAuthorization and test that it is called when and with the parameters that you expect. This allows you to test that your calls to the authorization methods are valid, along with the method itself.

    Separating the authorization into it's own type also allows you to more easily test that it is correct in isolation. In my (albeit limited) experience, using DI "patterns" give you vastly better separation of concerns and testability in your types as well as leading to a cleaner interface (this is obviously open to debate).

    My preferred mocking framework is RhinoMocks which is free and has very nice fluent interface but there are lots of others out there. If you'd like to know more about DI here are some good primers and .Net frameworks:

    • Martin Fowler on DI
    • Jeremy Miller on DI
    • Scott Hanselman's List of DI Containers
    • My personal favorite DI container: The Castle Project Windsor Container
    0 讨论(0)
  • 2020-12-31 20:50

    For question 1, it's best to perform authorization first. That way, you don't leak validation error messages back to unauthorized users.

    BTW, instead of using a home-grown authentication method (which I assume is what your CheckAccessPermission is), you might be able to hook up to WCF's out-of-the-box support for ASP.NET role providers. Once this is done, you perform authorization via OperationContext.Current.ServiceSecurityContext.PrimaryIdentity.IsInRole(). The PrimaryIdentity is an IPrincipal.

    0 讨论(0)
提交回复
热议问题