Authorisation in .NET with C# and WCF.

“You are unwise to lower your defenses.” – Darth Vader.

In an earlier post, we looked at programmatically creating WCF services in C#. These services could be secured with, for example, Windows authentication or Basic authentication. That’s great, with this we would know that the system knew the identity of the caller. However, we also need to look at restricting which of those identities is actually able to use the service.

Let’s look at a small example.

public void PerformFunction()
{
	// Determine Caller
	string strCaller = OperationContext.Current.ServiceSecurityContext.WindowsIdentity.Name;
}

In this example, we are able to determine the identity of the caller in the context of a WCF function call. When the WCF client calls the function PerformFunction(), assuming we have required authentication on the service host itself – we will be able to determine the caller’s identity.

However, at this point we most likely also want to restrict which users are authorised to use this function call. Now, there are many ways of doing this. As always, it depends on your requirements.

The most simple method would be to restrict the entirety of the function to a specific user or group (ideally a group).

private const string _strAuthorisedUsers = "Domain\\Application API Users";
		
[System.Security.Permissions.PrincipalPermission(SecurityAction.Demand, Role = _strAuthorisedUsers)]
public void PerformFunction()
{
	// Determine Caller
	string strCaller = OperationContext.Current.ServiceSecurityContext.WindowsIdentity.Name;
}

The PrincipalPermissions attribute, when applied to the function, allows us to restrict access using a variety of options. In the above example, access has been restricted to the Application API Users domain security group. However, there may be times when you need to change how a function operates based on the authorisation of the caller.


private const string _strAuthorisedFullAccessUsers = "Domain\\Application Full API Access";
private const string _strAuthorisedLimitedAccessUsers = "Domain\\Application Limited API Access";

public void PerformFunction()
{
	// Determine Caller
	System.Security.Principal.WindowsPrincipal principalCurrentUser = new System.Security.Principal.WindowsPrincipal(OperationContext.Current.ServiceSecurityContext.WindowsIdentity);

	// Check Authorisation
	if (principalCurrentUser.IsInRole(_strAuthorisedFullAccessUsers))
	{
		// Action
	}
	else if (principalCurrentUser.IsInRole(_strAuthorisedLimitedAccessUsers))
	{
			// Action
	}
	else
		throw new System.ServiceModel.Security.SecurityAccessDeniedException("Access denied.");
}

In the above example, we are actually determining the level of access to grant within the function, and then taking the appropriate action.

As with any development, there are numerous other options to achieve the requirement. The above options though provide two simple methods of providing authorisation to a WCF function call.

This works with the more traditional applications. I often use the first method to secure the function calls between the WCF client and the WCF server, however if the WCF client is a web application – I’ll often be using an application level authentication token instead – or both. I’ve used the first method with  windows authentication to provide authentication and authorisation between an  ASP.NET web site acting as the WCF client, to a windows service acting as the WCF server. I then also use application level authentication tokens for managing the user access within that application. But that as they say, is another story…

~ Mike

One thought on “Authorisation in .NET with C# and WCF.

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