Request for principal permission failed - probably due windows group?

2.7k views Asked by At

I googled for this error, didn't find correct answer.. 2 months ago I was doing MVC -> WCF communication. It worked, then I commented out PrincipalPermission attribute to get it working on localhost (VS IIS Express).

After re-enable I receiving error "Request for principal permission failed." I suppose my group is wrong.

WCF side:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
[PrincipalPermission(SecurityAction.Demand, Role = "Test_Group")]
public class TestService : ITestService
{
    public int Test()
    {
        return 0;
    }
}

Client side:

public async Task<ActionResult> Test()
    {
        Services.TestClientService testClient = new Services.TestClientService();
        testClient.ClientCredentials.Windows.ClientCredential = System.Net.CredentialCache.DefaultNetworkCredentials;
        testClient.ClientCredentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;

        try
        {
            int response = await testClient.TestAsync();
        }
        catch(Exception ex)
        {
            System.Diagnostics.Debug.WriteLine(ex.Message);
        }

        return View();
    }

WCF web config:

<system.serviceModel>
<behaviors>
  <serviceBehaviors>
    <behavior name="authBehavior">
      <!-- serviceAuthorizationManagerType="MyProject.Common.RoleAuthorizationManager, MyProject" -->
      <serviceAuthorization principalPermissionMode="UseWindowsGroups">
        <authorizationPolicies>
          <add policyType="MyProject.Common.AuthorizationPolicy, MyProject" />
        </authorizationPolicies>
      </serviceAuthorization>
      <serviceCredentials>
        <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="MyProject.Common.IdentityValidator, MyProject" />
        <serviceCertificate findValue="localhost" storeLocation="LocalMachine" x509FindType="FindBySubjectName" storeName="My" />
      </serviceCredentials>
      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="true" />
    </behavior>
    <behavior name="svcBehavior">
      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="true" />
    </behavior>
    <behavior name="">
      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="true" />
    </behavior>
  </serviceBehaviors>
</behaviors>
<bindings>
  <wsHttpBinding>
    <binding name="wsHttpEndpointBinding">
      <security mode="Message">
        <message clientCredentialType="Windows" />
      </security>
    </binding>
  </wsHttpBinding>
</bindings>
<services>
  <service name="MyProject.TestService" behaviorConfiguration="authBehavior">
    <endpoint address="" binding="wsHttpBinding" bindingConfiguration="wsHttpEndpointBinding" contract="MyProject.ITestService" />
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
  </service>
</services>
<!-- <protocolMapping>
  <add binding="wsDualHttpBinding" scheme="https" />
</protocolMapping>-->
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />

Client webconfig:

<system.serviceModel>
<behaviors>
  <endpointBehaviors>
    <behavior>
      <customInspector />
    </behavior>
  </endpointBehaviors>
</behaviors>
<bindings>
  <basicHttpBinding>
    <binding name="BasicHttpBinding" />
  </basicHttpBinding>
  <wsHttpBinding>
    <binding name="wsHttpEndpointBinding">
      <security mode="Message">
        <message clientCredentialType="Windows" />
      </security>
    </binding>
  </wsHttpBinding>
</bindings>
<extensions>
  <behaviorExtensions>
    <add name="customInspector" type="MyMVC.Services.WCF.Behavior, MyMVC" />
  </behaviorExtensions>
</extensions>
<client>
  <endpoint address="http://localhost:9999/TestService.svc"
    binding="wsHttpBinding" bindingConfiguration="wsHttpEndpointBinding"
    contract="MyMVC.Services.ITestService" name="wsHttpEndpointBinding_ITestService" />
</client>

I can't reach WCF AuthorizationPolicy.cs to check if Thread.CurrentPrincipal is set or not.

Any idea how to debug what's wrong? What I think it's problem of Test_Group in windows. WCF and MVC runs in IIS. MVC runs under IIS APPPOOL\MVC which is member of Test_Group.

Thanks for help.

2

There are 2 answers

0
user1085907 On BEST ANSWER

Move PrincipalPermission attribute from class level to method level.

Article: https://social.msdn.microsoft.com/Forums/vstudio/en-US/41c5a8c6-8d17-41c7-9714-4e47296ba75d/principalpermission-attribute-on-class-level-in-wcf-service?forum=wcf (last post mentions it can't be used on class level for WCF :/ )

11
Ben Morris On

Is the Test_Group a local group or one in Active Directory? If the latter it should be prefixed with your domain name followed by a back slash. So "Domain\Test_Group"

If not try removing the last attribute and place the following at the start of your function.

PrincipalPermission pp = new PrincipalPermission(null, @"Test_Group");
pp.Demand();