WCF security with AD functional groups
I have a WCF service running as a Windows service on intranet and I need to check that users accessing the service belong to certain AD functional groups. That is quite straightforward. I can call a method decorate开发者_如何学God with [OperationContract] that does that. However, can I enforce this check is performed each time the service is instantiated? I tried to call the method in the service's constructor but that doesn't seem to work.
My client is a WinForms app and I'm performing this security check when the main form's constructor which is not great. I would like to avoid hardcoding functional group names in attributes as the functional groups might change and I'd like them to be specified in the app.config file of the WCF service.
I'm contrained to .NET 3.0.
Thanks
By default, a WCF service will be either per-call or per-session, depending on your bdingin. The recommended best practise is per-call, and in this case, each request will:
- gets its own totally new, separate service class instance
- the service class will be instantiated
- the appropriate service method will be called, including all the checks for authorisation on the operation context
- the response will be returned to the caller
- the service class will be disposed of
You can enforce the per-call instantiation by applying a simple attribute to your service class - the implementation of your service contract:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
class YourServiceImplementation : IYourServiceContract
{
...
}
Read more on the topic here:
Discover Mighty Instance Management Techniques For Developing WCF Apps
I've implemented ServiceAuthorizationManager to handle authorization. However, it seems I cannot access Active Directory at the point the ServiceAuthorizationManager methods are called. The Thread.CurrentPrincipal.Identity.Name of my service is empty. I suspect this would be used as credentials when I query AD. If I try to query AD after my service class has been created though, it works and Thread.CurrentPrincipal.Identity.Name is filled correctly. The problem is I'd have to perform validation in each [OperationContract] method which just doesn't seem right.
I realize this is an ancient question, but for those who might need an answer, here is a code snippet I use to accomplish this:
public static void CheckPermissions(List<string> RequiredGroupNames)
{
bool ThrowException;
WindowsIdentity MyIdentity = OperationContext.Current.ServiceSecurityContext.WindowsIdentity;
WindowsPrincipal p = new WindowsPrincipal(MyIdentity);
ThrowException = true;
foreach (string RequiredGroupName in RequiredGroupNames)
{
if (p.IsInRole(RequiredGroupName))
{
ThrowException = false;
}
}
if (ThrowException == true)
{
throw new FaultException(MyIdentity.Name + ": You don't have permission for this operation!");
}
}
I used .NET 4.0 though, not 3.0 as OP stated. But I hope someone could find this helpful.
精彩评论