Identity & ServiceSecurityContext in WCF

Posted: July 25, 2010 in .NET, WCF
Tags: , ,

In an Windows environment every process(or code) executes under some valid user identity which is nothing but a authenticated Windows account.In .NET Framework we have the interface System.Security.Principal.IIdentity which provides the basic definition of identity.

public interface IIdentity
{ 

    string AuthenticationType { get; } //Type of Authentication (NTLM etc.)
    bool IsAuthenticated { get; } //Whether user is authenticated or not.
    string Name { get; } //Name of the account/user
} 

The most common implementation of this interface is the System.Security.Principal.WindowsIdentity class, which represents a Windows user.In this class two most commonly used methods are:

  • GetCurrent – This returns an WindowsIdentity object returning the current user.
  • Impersonate – This impersonates the running program with the identity represented by the WindowsIdentity object.

The following console program produces an output SANKARSAN\Administrator as I have logged into Windows using this account and running the console program.

static void Main(string[] args)
{
    Console.WriteLine(WindowsIdentity.GetCurrent().Name);
    Console.Read();
}

With this understanding of Windows Identity let’s move into how WCF stores information about the identity of the remote client.The System.ServiceModel.ServiceSecurityContext class is used for this purpose.It’s two most important properties are:

  • PrimaryIdentity – This is the identity used by the remote party for authentication while accessing the service.
  • WindowsIdentity – This is the WindowsIdentity object representing the Windows Account information used for Windows Authentication.

We can access the ServiceSecurityContext instance from WCF service operation in two ways:

  • ServiceSecurityContext.Current – Using the static Current property of ServiceSecurityContext  class.
  • OperationContext.Current.ServiceSecurityContext – Using the ServiceSecurityContext  property of OperationContext instance.

To get a clearer idea let’s consider a simple demo with a console hosted WCF service and console client.The service method prints out the value of PrimaryIdentity,WindowsIdentity,whether PrimaryIdentity and WindowsIdentity are same and the WindowsIdentity under which the host process is running.

public string GetIdentityInfo()
{
    string primaryIdentity = OperationContext.Current.ServiceSecurityContext.PrimaryIdentity.Name;
    string windowsIdentity = OperationContext.Current.ServiceSecurityContext.WindowsIdentity.Name;
    string processIdentity = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
    bool flag = windowsIdentity == primaryIdentity;
    return String.Format("Primary Identity {0},\nWindows Identity {1},\nWindows & Primary Identity Same? {2},\nProcess Identity {3}",
                          primaryIdentity, windowsIdentity,flag, processIdentity);
}

Here the service is deployed with wsHttpBinding and it’s default Security Mode, Message with ClientCredentialType Windows.

I am getting the following output while running both client & the service host as SANKARSAN\Administrator

Primary Identity SANKARSAN\Administrator,
Windows Identity SANKARSAN\Administrator,
Windows & Primary Identity Same? True,
Process Identity SANKARSAN\Administrator

On running the client as SANKARSAN\test and service as SANKARSAN\Administrator we get the following output:

Primary Identity SANKARSAN\test,
Windows Identity SANKARSAN\test,
Windows & Primary Identity Same? True,
Process Identity SANKARSAN\Administrator

This confirms that in case of both Windows Authentication both WindowsIdentity & PrimaryIdentity are same.

Now let’s change the clientCredentialType to UserName in Config and use a custom credential validation as shown below:

<bindings>
     <wsHttpBinding>
         <binding name="NewBinding0">
             <security>
                 <message clientCredentialType="UserName" negotiateServiceCredential="false"
                     establishSecurityContext="false" />
             </security>
         </binding>
     </wsHttpBinding>
 </bindings>

(For details of Custom Validator implementation you can refer to http://msdn.microsoft.com/en-us/library/aa702565.aspx)

In the client code I have provided the credentials as shown below:

static void Main(string[] args)
{
    TestServiceClient sc = new TestServiceClient();
    sc.ClientCredentials.UserName.UserName = "testuser";
    sc.ClientCredentials.UserName.Password = "testpwd";
    Console.WriteLine(sc.GetIdentityInfo());
    Console.Read();
}

Primary Identity testuser,
Windows Identity ,
Windows & Primary Identity Same? False,
Process Identity SANKARSAN\Administrator

So for custom authentication

  • WindowsIdentity will have
    • Name : blank
    • ImpersonationLevel :Anonymous.
    • IsAuthenticated : false
  • PrimaryIdentity will have
    • Name : Custom User Name
    • AuthenticationType: Name of the custom validator type.
    • IsAuthenticated : True

Then I changed the clientCredentialType to None as shown below:

<bindings>
    <wsHttpBinding>
        <binding name="NewBinding0">
            <security>
                <message clientCredentialType="None" />
            </security>
        </binding>
    </wsHttpBinding>
</bindings>

Now the output is:

Primary Identity ,
Windows Identity ,
Windows & Primary Identity Same? True,
Process Identity SANKARSAN\Administrator

So for authentication mode None

  • WindowsIdentity will have
    • Name : blank
    • ImpersonationLevel :Anonymous.
    • IsAuthenticated : false
  • PrimaryIdentity will have
    • Name : blank
    • AuthenticationType: blank.
    • IsAuthenticated : false

Here for simplicity we have used a console hosted service in the next post we will check out similar scenarios for IIS hosted service.

SourceCode

About these ads
Comments
  1. Identity & SecurityCallContext in WCF « Sankarsan’s Journal…

    Thank you for submitting this cool story – Trackback from DotNetShoutout…

  2. Identity & SecurityCallContext in WCF « Sankarsan’s Journal…

    Thank you for submitting this cool story – Trackback from PimpThisBlog.com…

  3. Identity & Service Security Context in WCF « Sankarsan’s Journal…

    Thank you for submitting this cool story – Trackback from Servefault.com…

  4. […] This post was mentioned on Twitter by techno@solidsoft, Sankarsan Bose. Sankarsan Bose said: Identity & SecurityCallContext in WCF http://dlvr.it/313QX […]

  5. gstarbuck says:

    Very nice, clear article – thank you!

  6. M.A. says:

    Hello,

    Nice article. I have a related question: I am interested in the remote client IP address calling WCF-BasicHttp web service. Can you please guide as to where I should be looking for that; in pipeline, orchestration, map some header settings on receive port etc.

    thanks..

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s