none
Error in Authentication using WCF services for Project server RRS feed

  • Question

  • I am getting following exception in set client end point method of WCF service call for Project server.

    Event Handler for event \ProjectPublishing\ of type \My_SPS_PWA_EventHandlers.My_PWA_EventHandler\ threw an exception: The HTTP request is unauthorized with client authentication scheme 'Ntlm'. The authentication header received from the server was 'NTLM,Basic realm="ps2010"'.

    It works perfect on Console application but throw this exception in Project server publishing event handler. What is dfferent here? I tried changing following to Windows or NTLM but same result.

     

                binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
                binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm;
                binding.Security.Transport.Realm = "";


    Moonis Tahir MVP SharePoint,MCTS SharePoint 2010/2007, MCPD.net, MCSD.net, MCTS BizTalk 2006,SQL 2005
    Friday, January 6, 2012 4:27 AM

Answers

  • Hi,

    The problem is most likely with the identity used when running as an Event, when you run your app from a console the client credential is the current user, but as an event it runs under the context of the Project Server Event Service.

    However from reading your code snippet I am wondering what type of authentication you are actually trying to use as "Realm" is not required if you just want standard NTLM auth.

    Perhaps you IIS web application has Digest authentication enabled?

     

    If you're using Claims-Forms or Kerberos then you will need to configure additional options.

    Here's a code snippet that I have handy for just this sort of requirement (ie NTLM only, no Claims, no Kerberos):

    <span style="white-space:pre">	</span>/// <summary>
            /// Programmatically set the WCF endpoint for the PSI client(s).
            /// </summary>
            /// <param name="pwaUid"></param>
            private void SetClientEndpoint(Guid pwaUid)
            {
                const int MAXSIZE = 500000000;
                const string svcRouter = "/_vti_bin/PSI/ProjectServer.svc";
    
                BasicHttpBinding binding = null;
    
                SPSite pwaSite = new SPSite(pwaUid);
    
                string pwaUrl = pwaSite.Url;
    
                if (pwaUrl.Contains("https:"))
                {
                    // Create a binding for HTTPS.
                    binding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
                }
                else
                {
                    // Create a binding for HTTP.
                    binding = new BasicHttpBinding(BasicHttpSecurityMode.TransportCredentialOnly);
                }
    
                binding.Name = "basicHttpConf";
                binding.SendTimeout = TimeSpan.MaxValue;
                binding.MaxReceivedMessageSize = MAXSIZE;
                binding.ReaderQuotas.MaxNameTableCharCount = MAXSIZE;
                binding.MessageEncoding = WSMessageEncoding.Text;
                binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm;
    
                // The endpoint address is the ProjectServer.svc router for all public PSI calls.
                EndpointAddress address = new EndpointAddress(pwaUrl + svcRouter);
    
                projectClient = new SvcProject.ProjectClient(binding, address);
                projectClient.ChannelFactory.Credentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
                projectClient.ChannelFactory.Credentials.Windows.AllowNtlm = true;
                
            }
    

    Hope that helps,


    Martin Laukkanen (Project Server Blog - www.nearbaseline.com/blog)
    • Marked as answer by Moonis Tahir Tuesday, January 10, 2012 5:57 PM
    Friday, January 6, 2012 7:02 AM

All replies

  • Hi,

    The problem is most likely with the identity used when running as an Event, when you run your app from a console the client credential is the current user, but as an event it runs under the context of the Project Server Event Service.

    However from reading your code snippet I am wondering what type of authentication you are actually trying to use as "Realm" is not required if you just want standard NTLM auth.

    Perhaps you IIS web application has Digest authentication enabled?

     

    If you're using Claims-Forms or Kerberos then you will need to configure additional options.

    Here's a code snippet that I have handy for just this sort of requirement (ie NTLM only, no Claims, no Kerberos):

    <span style="white-space:pre">	</span>/// <summary>
            /// Programmatically set the WCF endpoint for the PSI client(s).
            /// </summary>
            /// <param name="pwaUid"></param>
            private void SetClientEndpoint(Guid pwaUid)
            {
                const int MAXSIZE = 500000000;
                const string svcRouter = "/_vti_bin/PSI/ProjectServer.svc";
    
                BasicHttpBinding binding = null;
    
                SPSite pwaSite = new SPSite(pwaUid);
    
                string pwaUrl = pwaSite.Url;
    
                if (pwaUrl.Contains("https:"))
                {
                    // Create a binding for HTTPS.
                    binding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
                }
                else
                {
                    // Create a binding for HTTP.
                    binding = new BasicHttpBinding(BasicHttpSecurityMode.TransportCredentialOnly);
                }
    
                binding.Name = "basicHttpConf";
                binding.SendTimeout = TimeSpan.MaxValue;
                binding.MaxReceivedMessageSize = MAXSIZE;
                binding.ReaderQuotas.MaxNameTableCharCount = MAXSIZE;
                binding.MessageEncoding = WSMessageEncoding.Text;
                binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm;
    
                // The endpoint address is the ProjectServer.svc router for all public PSI calls.
                EndpointAddress address = new EndpointAddress(pwaUrl + svcRouter);
    
                projectClient = new SvcProject.ProjectClient(binding, address);
                projectClient.ChannelFactory.Credentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
                projectClient.ChannelFactory.Credentials.Windows.AllowNtlm = true;
                
            }
    

    Hope that helps,


    Martin Laukkanen (Project Server Blog - www.nearbaseline.com/blog)
    • Marked as answer by Moonis Tahir Tuesday, January 10, 2012 5:57 PM
    Friday, January 6, 2012 7:02 AM
  • I was missing the ProjectClient credentials setting and it was causing the security to fail. It got fixed. However it works as explicity credential passing. It does not work with CredentialCache.DefaultCredentials method. I wanted to use the Project server eventing service user context so that i dont have to manage a seperate credential passing etc. any way it worked for now.
    Moonis Tahir MVP SharePoint,MCTS SharePoint 2010/2007, MCPD.net, MCSD.net, MCTS BizTalk 2006,SQL 2005
    Tuesday, January 10, 2012 5:57 PM
  • Hi,

    If your having to use explicit credentials to get things going then that sounds to me like a Kerberos issue. The above code snippet was configured with NTLM authentication only and not Negotiate, to use Kerberos you need to change ClientCredentialType = HttpClientCredentialType.Windows, and then configure your SPN's etc correctly.

     

    HTH,


    Martin Laukkanen (Project Server Blog - www.nearbaseline.com/blog)
    Tuesday, January 10, 2012 10:24 PM