3 Replies Latest reply on Oct 23, 2013 8:25 PM by Bhess

    Issue with PI Web Services and Delegation - Multiple Logins established

    nthorson

      I am having an issue with delegation and need assistance to determine what the problem is.  Basically, when I invoke a PI Web Service, two logins to PI Server are created.  The first login uses my account, i.e. n1thors.  This is the desired behavior.  

       

      Successful login  ID: 15509. Address: 161.201.170.46. Name: w3wp.exe(936):remote. Identity List: piadmin | piadmins | PIAdministrators  | PIWorld. Environment Username : Business\n1thors. Method: Windows Login (SSPI,Kerberos)

       

      The second login uses the name of the server, i.e. CGOOSI16.  

       

      Successful login  ID: 15509. Address: 161.201.170.46. Name: w3wp.exe(936):remote. Identity List: pidemo | piusers | PIWorld. Environment Username : Business\CGOOSI16$. Method: Windows Login (SSPI,Kerberos)

       

      The latter of the two logins trumps the former and I am only able to see data that CGOOSI can see.  If I remove the CGOOSI mapping, PI web services tries to connect to PI Server twice as CGOOSI16.  Both of those logins fail.  

       

      The method I am trying to invoke is GetPISnapshotData( string[] paths).  

       

      Here are my configuration parameters.

       

      1.  In IIS, only Windows authentication is enabled 

       

         a.  The provider is set to Negotiate:Kerberos

       

         b.  Kernel mode authentication is disabled

       

      2.  The PI Web Services Application Pool runs as NetworkService (according to the documentation, this is the easiest way to get things up and running since I don't have to worry about SPN)

       

         a.  Managed pipeline is set to integrated

       

         b.  .NET is set to 4.0

       

      3.  In PISDK on the IIS Server, PI Trust and Default User have been disabled

       

      4.  All machines are on the domain

       

      Below are my web.config and app.config files

       

       Web.config

       
      <?xml version="1.0" encoding="UTF-8"?>
      <!--
          Note: As an alternative to hand editing this file you can use the 
          web admin tool to configure settings for your application. Use
          the Website->Asp.Net Configuration option in Visual Studio.
          A full list of settings and comments can be found in 
          machine.config.comments usually located in 
          \Windows\Microsoft.Net\Framework\v2.x\Config 
      -->
      <configuration>
        <configSections>
          <section name="PIWebServiceSettings" type="System.Configuration.AppSettingsSection, System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" requirePermission="false" />
          <section name="pidsSettings" type="System.Configuration.AppSettingsSection, System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" requirePermission="false" />
          <section name="PIOLEDBEnterpriseInitializationProperties" type="System.Configuration.AppSettingsSection, System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" requirePermission="false" />
        </configSections>
        <PIWebServiceSettings>
          <add key="AllowCalculations" value="true" />
          <add key="AllowDataEntry" value="true" />
          <add key="FloatPrecision" value="DisplayDigits" />
          <add key="UpdatePurgeInterval" value="5" />
        </PIWebServiceSettings>
        <pidsSettings>
          <add key="PIinstrumentationConfigFile" value="C:\Program Files\PIPC\PI Web Services\PIInstrumentation.config" />
        </pidsSettings>
        <PIOLEDBEnterpriseInitializationProperties>
          <!--Refer to the PI OLEDB Enterprise users manual for more information on 
              general OLEDB initialization properties, and for those specific to
              PI OLEDB Enteprise-->
          <add key="Command Timeout" value="120" />
          <!--
          <add key="Log File" value="C:\path\to\logfile.log" />
          <add key="Log Level" value="1" />
          -->
        </PIOLEDBEnterpriseInitializationProperties>
        <appSettings>
        </appSettings>
        <connectionStrings />
        <system.web>
          <compilation debug="false" targetFramework="4.0">
            <assemblies>
              <add assembly="System.Configuration.Install, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A" />
              <add assembly="System.Management, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A" />
              <add assembly="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
              <add assembly="OSIsoft.PIDataServices.DataAccess, Culture=neutral, PublicKeyToken=53b77d1d3d7a979b" />
              <add assembly="OSIsoft.PIDataServices.Common, Culture=neutral, PublicKeyToken=53b77d1d3d7a979b" />
              <add assembly="OSIsoft.PIDataServices.Configuration, Culture=neutral, PublicKeyToken=53b77d1d3d7a979b" />
              <add assembly="OSIsoft.PIDataServices.DataService, Culture=neutral, PublicKeyToken=53b77d1d3d7a979b" />
              <add assembly="OSIsoft.PIInstrumentation, Culture=neutral, PublicKeyToken=53b77d1d3d7a979b" />
              <add assembly="OSIsoft.PIInstrumentation.Listeners, Culture=neutral, PublicKeyToken=53b77d1d3d7a979b" />
            </assemblies>
          </compilation>
      
          <!--
                  The <authentication> section enables configuration 
                  of the security authentication mode used by 
                  ASP.NET to identify an incoming user. 
              -->
          <authentication mode="Windows" />
          <identity impersonate="false" />
          <customErrors mode="Off" defaultRedirect="GenericErrorPage.htm">
            <error statusCode="403" redirect="NoAccess.htm" />
            <error statusCode="404" redirect="FileNotFound.htm" />
          </customErrors>
          <pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID" />
        </system.web>
        <system.serviceModel>
          <serviceHostingEnvironment aspNetCompatibilityEnabled="false" />
          <!-- Uncomment this section and the system.diagnostics section above to enable WCF diagnostics 
           <diagnostics wmiProviderEnabled="true" performanceCounters="Default">
              <messageLogging logEntireMessage="true" logMalformedMessages="true"
                 logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true" />
           </diagnostics>-->
          <bindings>
            <wsHttpBinding>
              <binding name="wsBinding_2011" sendTimeout="00:01:00" receiveTimeout="00:01:00" bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
                <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" />
                <security mode="Transport">
                  <transport clientCredentialType="Windows" />
                </security>
                <readerQuotas maxStringContentLength="1000000" />
              </binding>
            </wsHttpBinding>
            <mexHttpsBinding>
              <binding name="mexBinding" />
            </mexHttpsBinding>
          </bindings>
          <services>
            <service behaviorConfiguration="DefaultServiceBehavior" name="PIWebServices.PIDataService.PITimeSeriesSvcImpl">
              <endpoint binding="wsHttpBinding" bindingConfiguration="wsBinding_2011" name="TimeSeriesEndpoint" bindingNamespace="http://xml.osisoft.com/services/PIDataService" contract="PIWebService.PIDataService.IPITimeSeries">
              </endpoint>
              <endpoint address="mex" binding="wsHttpBinding" bindingConfiguration="wsBinding_2011" name="mexBasicEndpoint" contract="IMetadataExchange" />
            </service>
            <service behaviorConfiguration="DefaultServiceBehavior" name="PIWebServices.PISearchService.PISearchSvcImpl">
              <endpoint binding="wsHttpBinding" bindingConfiguration="wsBinding_2011" name="SearchEndpoint" bindingNamespace="http://xml.osisoft.com/services/PISearchService" contract="PIWebServices.PISearchService.IPISearch">
              </endpoint>
              <endpoint address="mex" binding="wsHttpBinding" bindingConfiguration="wsBinding_2011" contract="IMetadataExchange" />
            </service>
            <service behaviorConfiguration="DefaultServiceBehavior" name="OSIsoft.PIWebServices.Services.PISoapServiceImpl">
              <endpoint binding="wsHttpBinding" bindingConfiguration="wsBinding_2011" name="SoapEndpoint" bindingNamespace="http://xml.osisoft.com/services/PISoapService" contract="OSIsoft.PIWebServices.Services.IPISoapService">
              </endpoint>
              <endpoint address="mex" binding="wsHttpBinding" bindingConfiguration="wsBinding_2011" contract="IMetadataExchange" />
            </service>
          </services>
          <behaviors>
            <serviceBehaviors>
              <behavior name="DefaultServiceBehavior">
                <serviceMetadata httpsGetEnabled="true" />
                <serviceDebug includeExceptionDetailInFaults="true" />
                <serviceCredentials>
                  <windowsAuthentication includeWindowsGroups="true" allowAnonymousLogons="false" />
                  <issuedTokenAuthentication allowUntrustedRsaIssuers="true" />
                </serviceCredentials>
                <serviceAuthorization principalPermissionMode="UseWindowsGroups" impersonateCallerForAllOperations="true" />
              </behavior>
            </serviceBehaviors>
          </behaviors>
        </system.serviceModel>
        <system.webServer>
          <validation validateIntegratedModeConfiguration="false"/>
      
          <defaultDocument>
            <files>
              <add value="PITimeSeries.svc" />
            </files>
          </defaultDocument>
        </system.webServer>
      </configuration>
      

       app.config

       

       

       
      <?xml version="1.0" encoding="utf-8" ?>
      <configuration>
          <system.serviceModel>
              
              <bindings>
                  <wsHttpBinding>
                      <binding name="TimeSeriesEndpoint">
                          <security mode="Transport" />
                      </binding>
                  </wsHttpBinding>
              </bindings>
              <client>
                  <endpoint address="https://cgoosi16/PITimeSeries.svc" behaviorConfiguration="DefaultClientBehavior"
                      binding="wsHttpBinding" bindingConfiguration="TimeSeriesEndpoint"
                      contract="ServiceReference1.IPITimeSeries" name="TimeSeriesEndpoint">
                      <identity>
                          <servicePrincipalName value="HOST/CGOOSI16" />
                      </identity>
                  </endpoint>
              </client>
              <behaviors>
                <endpointBehaviors>
                  <behavior name="DefaultClientBehavior">
                    <clientCredentials>
                      <windows allowedImpersonationLevel="Delegation" />
                    </clientCredentials>
                  </behavior>
                </endpointBehaviors>
              </behaviors>
          </system.serviceModel>
      </configuration>
      

       

        • Re: Issue with PI Web Services and Delegation - Multiple Logins established
          Bhess

          Nick,

           

          This is known and expected behavior in PI Web Services.  PI Web Services retrieves some data and metadata using the process identity rather than the identity of the logged in user.  This allows PI Web Services to maintain a user-agnostic cache, so that if a second user with different credentials requests similar data, the data can be supplied from the cache.  In this case, data is retrieved from the PI Server using the process identity, and data security is applied on the PI Web Services server.

           

          In order for this to work, PI Web Services makes the assumption that the process identity has read privileges on the data and metadata that will be accessed.  So the solution to your problem is to grant the process account for PI Web Services (in your case, it's the default "Network Service", i.e. "DOMAIN\MACHINENAME$") at least the same privileges as the users who will be using PI Web Services.

           

          Hope that clears things up.

           

          Brad

          1 of 1 people found this helpful
            • Re: Issue with PI Web Services and Delegation - Multiple Logins established
              nthorson

              Brad,

               

              Yes that definitely helps!  Thanks!  That being said, is this behavior documented somewhere?  It is not at all intuitive.

               

              Nick

                • Re: Issue with PI Web Services and Delegation - Multiple Logins established
                  Bhess

                  Nick,

                   

                  The behavior is noted in the manual, though you'd have to infer that the Process ID needs at least the same read privileges as the User ID, even when Windows Integrated Authentication is used:

                   

                  PI Web Services 2012 > PI Web Services security > User accounts required for secure connections

                   

                  "PI Web Services uses the Process ID to connect to and process updates from the PI System through PI Data Services. If PI Data Services cannot use the IIS Process ID to connect to the PI System, PI Web Services will return an error that data cannot be retrieved."

                   

                  Thanks for bringing this to our attention, as I had mistakenly thought that our documentation was a bit more clear on this point.

                   

                  Best,

                   

                  Brad