开发者

How to call a WCF service from a unit test as an anonymous identity?

I've a SecurityService that has a AutoLogin method, that uses the ServiceSecurityContext to find out which windows identity is calling and then tries to find the related user account in the database. This is working fine when it is called from a web site that uses impersonation and requires integrated security in IIS. The call is using the stock NetPipeBinding.

I'd like to test the service as follows:

[TestMethod]
public void AutoLoginAsAnonymousFails()
{
    using (var anonymousContext = WindowsIdentity.Impersonate(WindowsIdentity.GetAnonymous().Token))
    {
        ISecurityService securityService = ClientChannelManager.CreateSecurityServiceChannel();
        var loginResponse = securityService.AutoLogin();
        ((ICommunicationObject)securityService).Close();
        Assert.IsFalse(loginResponse.IsSuccessful);             
    }
}

On the service side the user in the securitycontext is always me - how to make it an anonymous user? I've already tried to impersonate the IntPtr.Zero but without success.

For reference the relevant part of the service method:

pu开发者_如何学Goblic ResponseMessage AutoLogin()
{
    if (ServiceSecurityContext.Current.WindowsIdentity != null
        && !ServiceSecurityContext.Current.WindowsIdentity.IsAnonymous
        && !ServiceSecurityContext.Current.WindowsIdentity.IsGuest
        && ServiceSecurityContext.Current.WindowsIdentity.IsAuthenticated)
    {
        // find the user based on his windows identity and return success = true message
    }

    // return success = false message
}


This is a classic example of how separation of concerns could help you. Instead of relying directly on ServiceSecurityContext (something that one should, IMO, never do), make sure to configure your service so that security information is instead encapsulated in Thread.CurrentPrincipal.

IIRC, when you use Windows authentication and impersonation, it may even set this up for you automatically, but otherwise, you can always write a custom ServiceAuthorizationManager, that does this for you.

This will allow you to vary your security concerns independently of your domain logic. If you stick with the IPrincipal interface and resist the temptation of downcasting to WindowsPrincipal, your code will even be ready for the future of identity: Claims-based Identity, as implemented by the Windows Identity Foundation (WIF).

This also helps tremenduously with unit testing, because you can then just assign a GenericPrincipal to Thread.CurrentPrincipal before invoking your System Under Test (SUT).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜