Securing WCF Services: Preventing Unauthorized Access

Suppose you are writing a web service to perform a sensitive calculation. Your web service should only be accessible by authorized users and/or applications. Here’s my advice for configuring your service:

Use .NET to Your Advantage

.NET has built in features for ensuring that the code calling yours is authorized to do so. For example, take a look at this snippet of code:

[PrincipalPermission(SecurityAction.Demand, Role = "MyLocalSecurityGroup"]
public SearchResults Find(string contractNumber)
{
    ...
}

Notice the [PrinciplePermission] attribute. This attribute tells .NET that only principals who are members of the "MyLocalSecurityGroup" role are allowed to run this method (where a principal is a user/service account, and a role is a locally defined security group on the server). In other words, in order to run this method, the caller must be running under an account that is a member of the local security group specified.

Local Security Groups

By telling your code to check a security group on the local server, you get around the problem of having to care about the different test regions in your code. The local group on your DEV server will contain only those accounts which are authorized to access the service in DEV. Likewise, the TST and PRD local security groups will only contain accounts authorized to access TST and PRD respectively.

Domain Security Groups (NT Groups)

Of course, you don’t want to manage access at the local server level. Rather, you want to let User Account Services (UAS) manage access centrally. The way to do this is to create domain security groups for each test level. For the middleware, I created these groups.

  • MyDomainSecurityGroup.DEV
  • MyDomainSecurityGroup.TST
  • MyDomainSecurityGroup.PRD

Then update the local security groups on your servers to ONLY contain one of these domain security groups. If the server is a DEV server, put the DEV make the DEV domain group the only member of the local security group. All other user/service accounts should be removed from the local security group and added to the appropriate domain security group.

Conclusion

If you follow this pattern to secure your web services, you’ll be able to prevent unauthorized access to your service by adding a single line of code to every method that needs to check authorization. Furthermore, in a more complex scenario – say one where users may have read, write or admin access to your service – you can create as many local and domain security groups as you need to ensure that users and applications have the lowest level of access required to do their work.

One final thought: If you web service is hosted in across a pool of servers, remember to create the local security groups on all of the servers. You could probably do this with your installer. Or, you could make it a manual step in your implementation plan that only gets executed once.