locked
No custom principal is specified in the authorization context. RRS feed

  • Question

  • I'm getting the "No custom principal is specified in the authorization context" error when I try to connect to my service. When I debug, the Evaluate method on my IAuthorizationPolicy implementation does not have anything in the evaluationContext.Properties collection.

    I have defined my methods like so:

    Code Snippet

    [ServiceContract()]
    public interface INotebookUploadService
    {
    ...
        [OperationContract]
        string CheckFileHash(string FileName);
    ...
    }

    public class NotebookUploadService : INotebookUploadService
    {
    ...
        [UploadNotebookClaim(SecurityAction.Demand)]
        [DownloadNotebookClaim(SecurityAction.Demand)]
        [OperationBehavior(Impersonation = ImpersonationOption.Required)]
        public string CheckFileHash(string FileName)
    ...
    }



    (see end of message for config files)

    I am calling it like this:

    Code Snippet

    wcf = new NotebookUploadServiceClient("NotebookUpload");
    wcf.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;

    ...

    this.MaxRequestLength = Math.Max(1, (this.WebService.GetMaxRequestLength() * 1024) - (2 * 1024))


    And that's where I get the exception.

    When I look at the code generated by svcutil.exe from the wsdl emitted by the .svc, I don't see any references to impersonation or claims. Should I? I can't figure out what I'm missing in my setup that is causing things to fail. The server and client are on the same machine.

    Thanks.

    Colin

    App.config:

    Code Snippet

      <system.serviceModel>
        <bindings>
          <wsHttpBinding>
            <binding name="NotebookUpload" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false"
                transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
              <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
              <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" />
              <security mode="Message">
                <transport clientCredentialType="Windows" proxyCredentialType="Ntlm" realm="" />
                <message clientCredentialType="None" negotiateServiceCredential="false" algorithmSuite="Default" establishSecurityContext="false" />
              </security>
            </binding>
          </wsHttpBinding>
        </bindings>
        <behaviors>
          <endpointBehaviors>
            <behavior name="uploadBehavior">
              <clientCredentials>
                <windows allowedImpersonationLevel="Impersonation" />
              </clientCredentials>
            </behavior>
          </endpointBehaviors>
        </behaviors>
        <client>
          <endpoint address="http://mypc.myaddress.com/NoMaDServices/NotebookUploadService.svc" binding="wsHttpBinding" bindingConfiguration="NotebookUpload" contract="NotebookUpload.INotebookUploadService" name="NotebookUpload" behaviorConfiguration="uploadBehavior">
            <identity>
              <certificate encodedValue="AwAAAAEAAAAUAAAAUykfkG2nGBX69t7O7FCVY1VN3wogAAAAAQAAAMcBAAAwggHDMIIBcaADAgECAhBQhjcdq4d+rkrUhYJGaFzsMAkGBSsOAwIdBQAwFjEUMBIGA1UEAxMLUm9vdCBBZ2VuY3kwHhcNMDcwODIyMTg1OTM0WhcNMzkxMjMxMjM1OTU5WjAmMSQwIgYDVQQDExtjYW0tZDA0NTcyMy5jb3JwLmJpb2dlbi5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAN6PTqGrdMqvo8muhsf8S41Ebnm+YvYzhVkkSZuu6w9aMVa+jTcpL8aCeAgUfXpdmNqDPpt7g7H8Pn08CZVwdFmQAsjtW7Q1UEBDVHgfCifZIC+wWvT8h8Ns1/q+ijioflyTSWxB29wRPuSwQLodT9mGPEFDvn+PqnMWEvIQE9ZzAgMBAAGjSzBJMEcGA1UdAQRAMD6AEBLkCS0GHR1PAI1hIdwWZGOhGDAWMRQwEgYDVQQDEwtSb290IEFnZW5jeYIQBjdsAKoAZIoRz7jUqlw19DAJBgUrDgMCHQUAA0EAArAGfgVYfycWjQ1zaNg//yh4tqr2fqDHSq2tuIT6R3WAduRXo58lqJzqgBUhPVR3iG/ZkhMwDe5cEhg2QTyTEA==" />
            </identity>
          </endpoint>
        </client>
      </system.serviceModel>



    web.config:

    Code Snippet

        <system.serviceModel>
        <bindings>
          <wsHttpBinding>
            <binding name="WSHttpBinding_INotebookUploadService">
              <security mode="Message">
                <transport clientCredentialType="Windows" proxyCredentialType="Ntlm" realm="" />
                <message clientCredentialType="None" negotiateServiceCredential="false" algorithmSuite="Default" establishSecurityContext="false" />
              </security>
            </binding>
          </wsHttpBinding>
        </bindings>
        <behaviors>
          <serviceBehaviors>
            <behavior name="Behavior_INotebookUploadService">
              <serviceMetadata httpGetEnabled="true"/>
              <serviceDebug includeExceptionDetailInFaults="true"/>
              <serviceAuthorization principalPermissionMode="Custom">
                <authorizationPolicies>
                  <add policyType="TransferService.Claims.ClaimsAuthorizationPolicy, Notebook Common" />
                </authorizationPolicies>
              </serviceAuthorization>
              <serviceCredentials>
                <userNameAuthentication userNamePasswordValidationMode="Windows" />
                <serviceCertificate storeLocation="CurrentUser" storeName="TrustedPeople" findValue="mypc.myaddress.com" x509FindType="FindBySubjectName" />
              </serviceCredentials>
            </behavior>
          </serviceBehaviors>
        </behaviors>
        <services>
                <service behaviorConfiguration="Behavior_INotebookUploadService" name="TransferService.NotebookUploadService">
                    <endpoint address="http://mypc.myaddress.com/NoMaDServices/NotebookUploadService.svc"
                      binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_INotebookUploadService"
                      name="NotebookUpload" contract="TransferService.INotebookUploadService"/>
                    <endpoint address="mex" binding="mexHttpBinding" name="MetaData" contract="IMetadataExchange"/>
                </service>
            </services>
        </system.serviceModel>



    Friday, September 14, 2007 3:55 PM

Answers

  • This one is kind of tricky. You'll need to add a special ServiceAuthorizationManager as well and override CheckAccessCore(OperationContext oc). In CheckAccessCore, if the rights pass, you need to assign a Principal to the AuthorizationContext like so:

    Code Snippet

    // Probably not the best idea here-- but it gives you the gist of what needs

    // to happen

     

    operationContext.ServiceSecurityContext.AuthorizationContext.Properties["Principal"] =

    System.Threading.Thread.CurrentPrincipal;

     

     

     

    This is one of those things that is easiest to figure out by looking at the callstack  in tracing and then using Reflector to figure things out. Thanks for the interesting challenge!

     

    Saturday, September 15, 2007 12:43 AM

All replies

  • This one is kind of tricky. You'll need to add a special ServiceAuthorizationManager as well and override CheckAccessCore(OperationContext oc). In CheckAccessCore, if the rights pass, you need to assign a Principal to the AuthorizationContext like so:

    Code Snippet

    // Probably not the best idea here-- but it gives you the gist of what needs

    // to happen

     

    operationContext.ServiceSecurityContext.AuthorizationContext.Properties["Principal"] =

    System.Threading.Thread.CurrentPrincipal;

     

     

     

    This is one of those things that is easiest to figure out by looking at the callstack  in tracing and then using Reflector to figure things out. Thanks for the interesting challenge!

     

    Saturday, September 15, 2007 12:43 AM
  • hmm,

     

    Could you please try this

     

    Instead of

    Code Snippet

    wcf.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;

     

     

    try this

    Code Snippet

    wcf.ChannelFactory.Credentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;

     

     

    ?

    allan

    Saturday, September 15, 2007 5:29 AM
  • I will try that when I get back into the office Monday morning. Thanks for the reply.

    Colin

    Saturday, September 15, 2007 12:07 PM
  • Tried that, but still no luck: Client cannot determine the Service Principal Name based on the identity in the target address

    If I use clientCredentialType="UserName" on the message security, I can get the service working if I hardcode (or collect and specify at runtime) the username/password. What I really want to do is be able to just connect as whoever is running the client code and "log in" on the server as that identity without my code ever needing to handle the password. I don't get why this scenario is so hard to find an example of (all the ones I've found assume that I've got an ASP.Net membership provider that I'll be using -- we have a custom home-grown authentication system that predates ASP.Net).

    Any tips on getting windows authentication working are appreciated.

    Thanks for the help so far. It's what's got me to where I am now.

    Colin

    Monday, September 17, 2007 8:51 PM
  • Your answer doesn't provide any context or incite into the question asked. What is happening here, why does your answer work?

    Tuesday, August 12, 2014 3:21 AM