none
WCF, MSMQ, and Declarative permissions (PrincipalPermission) RRS feed

  • Question

  • I have a WCF MSMQ service that I'm trying to get declarative permissions working with.  I'm able to send messages locally and remotely, but whenever I add the declarative permissions I'm getting the below error.

    System.Security.SecurityException - "Request for principal permission failed."

    The ServiceSecurityContext.Current.PrimaryIdentity is filled out with the correct Identity.  For for the ServiceSecurityContext.Current.WindowsIdentity the IsAnonymous value is true.

    I created a NetTCP endpoint for my service and it passes along the users identity just fine.  In other words, I don't get a security exception and my code execute just fine.

    Any ideas?

    Monday, June 16, 2014 4:43 PM

All replies

  • Hi,

    Without your code, I do not know how did you add the PrincipalPermission. Then please try to check the following to see if you have done something wrong.

    In WCF this can be done with an imperative permission demand within the WCF operation or any business component. Just create a PrincipalPermission object, initialize the values you want to enforce, and issue the Demand().

    public string AdminsOnly()
    {
      // unprotected code
        
      PrincipalPermission p = new
    PrincipalPermission(null, "Administrators");
      p.Demand();
      
      // protected code
    }
    

    In this example, an exception will be thrown if the user is not in the Administrators group.

    You can also place a declarative PrincipalPermissionAttribute on any WCF operation or business component method to apply the demand before the operation or method is invoked:

    [PrincipalPermission(SecurityAction.Demand, Role =
    "Administrators")]
    public string AdminsOnly()
    {
      // protected code
    }
    

    This approach is preferable since it decouples the security requirements from the actual code within the operation.

    Also I am not sure which security mode you are using, then please try to check the following articles:
    #Securing Messages in MSMQ Using Transport Security:
    http://msdn.microsoft.com/en-us/library/ms789030(v=vs.110).aspx .

    #Securing Messages in MSMQ Using Message Security:
    http://msdn.microsoft.com/en-us/library/ms789036(v=vs.110).aspx .

    Best Regards,
    Amy Peng


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Tuesday, June 17, 2014 7:53 AM
    Moderator
  • I was using the declarative PrincipalPermissionAttribute.  After playing around a bit I think I made some progress.  I've been using both the WCF test client on the server and a small test client.  I was testing out a few things locally, my issues seem to be the account that I'm running my IIS app pool under.

    When I use my windows domain account for the app pool and the WCF test client locally I get the below errors.

    - The token provider cannot get tokens for target 'net.msmq://{computerName}/private/WcfServiceExampleMSMQ/Service1.svc'.

    - The NetworkCredentials provided were unable to create a Kerberos credential, see inner exception for details.

    - Inner Exception: Authenticating to a service running under a user account which requires Kerberos multilegs, is not supported.

    - Inner Exception: The function completed successfully, but must be called again to complete the context

    I switched the app pool Identity over to Network service (thinking that it wouldn't need to make a Kerberos hop to validate) and everything started working locally with the WCF Test Client.

    Below are my bindings for the client.

    <netMsmqBinding>
          <binding name="NetMsmqBinding_IService1" 
                   exactlyOnce="true" durable="true"                      
                   useActiveDirectory="false">
            <security mode="Both">
               <message clientCredentialType="Windows" />
               <transport msmqProtectionLevel="Sign" 
                  msmqAuthenticationMode="WindowsDomain" />
           </security>
      </binding>
    </netMsmqBinding>

    I switched to my remote client to use msmqProtectionLevel of EncryptAndSign and useActiveDirectory="true" I got the below error - 

    An error occurred when converting the '{computername}\private$\wcfserviceexamplemsmq/service1.svc' queue path name to the format name: The queue path name specified is invalid. (-1072824300, 0xc00e0014). All operations on the queued channel failed. Ensure that the queue address is valid. MSMQ must be installed with Active Directory integration enabled and access to it is available.

    Overall I think I making progress, but I don't have everything working the way I like.

    Tuesday, June 17, 2014 3:54 PM
  • So I found some information concerning using 

    <message clientCredentialType="Windows"/>

    http://msdn.microsoft.com/en-us/library/ms789036.aspx

    "Note that when using this credential type, the service must be running under the SERVICE account."

    So I appears that my App Pool has to run under "Network Service" if I want to use the declarative PrincipalPermissionAttribute.  Which I don't know if that will work in my environment, but I it good to know.

    Of course you can use ServiceSecurityContext.Current.PrimaryIdentity to validate any permissions that you need to validate.

    I suspect if that you'll have to build a behavior or some short of extension to keep from having to paste the code below in every method.

    var pc = new PrincipalContext(ContextType.Domain);
    
    var up = UserPrincipal.FindByIdentity(pc, 
                      IdentityType.SamAccountName,
         ServiceSecurityContext.Current.PrimaryIdentity.Name);
    
    var groups = up.GetAuthorizationGroups();
    
    if (!groups.Any(p => p.Name == "{Your Group Name}"))
       return;



    Tuesday, June 17, 2014 8:38 PM