8 Replies Latest reply on May 31, 2012 1:03 PM by spilon

    Error accessing PI Webservice (C#.Net)

    eweewee

      Hi All,

       

      I have writen a sample code to acces PI Webservices but receive an error when I run the code. Can you help me with this?

       

      As I run the code on a different computer I got an authentication error (see attachment error1).

       

      When running the code on the same computer where the WebService is installed I got another error message (see attachment error1). my piserver name is pi.magion.nl.

       

      5381.error1.png

       

       7558.error2.png

       

      sample code : 

       

       

       
      using System;
      
      using System.Collections.Generic;
      
      using System.Linq;
      
      using System.Text;
      
      using System.Windows.Forms;
      
      namespace ConsoleApplication1
      
      {
      
      class Program
      
      {
      
      static void Main(string[] args)
      
      {
      
      PITimeSeriesRef.PITimeSeriesClient proxy = new PITimeSeriesRef.PITimeSeriesClient("BasicEndpoint");
      
      
      
      // set up for a single request -- the WS supports multiple requests returning multiple time series
      
      PITimeSeriesRef.PIArcDataRequest[] reqs = new PITimeSeriesRef.PIArcDataRequest[1];
      
      PITimeSeriesRef.PIArcDataRequest req = new PITimeSeriesRef.PIArcDataRequest();
      
      // set the request time range from the controls
      
      PITimeSeriesRef.TimeRange tr = new PITimeSeriesRef.TimeRange();
      
      tr.Start = "-2h";
      
      tr.End = "*";
      
      req.TimeRange = tr;
      
      // set the manner using some assumptions
      
      PITimeSeriesRef.PIArcManner arcmnr = new PITimeSeriesRef.PIArcManner();
      
      arcmnr.Boundaries = PITimeSeriesRef.PIArcMannerBoundaries.Inside;
      
      arcmnr.NumValues = 100;
      
      arcmnr.RetrievalType = PITimeSeriesRef.PIArcMannerRetrievalType.Compressed;
      
      arcmnr.Updates = false;
      
      // arcmnr.Filter = "sinusoid";
      
      req.PIArcManner = arcmnr;
      
      // set the path
      
      req.Path = "pi://pi.magion.nl/sinusoid";
      
      reqs[0] = req;
      
      try
      
      {
      
      Console.WriteLine(proxy.ClientCredentials.UserName);
      
      Console.WriteLine(req.Path);
      
      // call the web service through the proxy
      
      PITimeSeriesRef.TimeSeries[] rts = proxy.GetPIArchiveData(reqs);
      
      if (rts.Length >= 1)
      
      {
      
      // extract the (expected) single time series
      
      PITimeSeriesRef.TimeSeries ts = rts[0];
      
      if (ts.Error != 0)
      
      {
      
      Console.WriteLine("timeseries error " + ts.ErrDesc);
      
      }
      
      foreach(PITimeSeriesRef.TimedValue value in ts.TimedValues)
      
      {
      
      string line = "";
      
      if (value.Value != null && value.Time != null)
      
      {
      
      line = value.Value + "\t\t" + value.Time.ToString("yyyy'-'MM'-'dd'T'HH':'ss'.'FK'");
      
      Console.WriteLine(line);
      
      
      
      
      
      }
      
      else
      
      {
      
      Console.WriteLine("no values found");
      
      }
      
      }
      
      }
      
      }
      
      catch (Exception ex)
      
      {
      
      MessageBox.Show(ex.Message);
      
      Console.WriteLine("cannot retrieve data " + ex.Message);
      
      
      
      
      
      }
      
      finally
      
      {
      
      if (proxy.State == System.ServiceModel.CommunicationState.Opened)
      
      {
      
      proxy.Close();
      
      }
      
      
      
      }
      
      
      
      
      
      
      
      }
      
      }
      
      }
      

       

       

       

       

       

        • Re: Error accessing PI Webservice (C#.Net)
          MvanderVeeken

          Could you share the web.config of PI Web Services? And maybe the system.servicemodel section of your client's app.config?  If you could attach them in files to your post, or use the 'Insert Code' option when you click 'Use rich formatting'.

           

          In your code you are using the basicBinding (basicHttpBinding), which has security turned of by default. basicHttpBinding uses message security, and wsHttpBinding has Windows security by default. It depends on what you have configured server side (and the generated client side configuration).

            • Re: Error accessing PI Webservice (C#.Net)
              eweewee

              Hi Michael,

               

              Here you have the 2 configuration files

               

              App.config :

               

              <?xml version="1.0" encoding="utf-8" ?>
              <configuration>
                  <system.serviceModel>
                      <bindings>
                          <wsHttpBinding>
                              <binding name="BasicEndpoint" 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="None"
                                          realm="" />
                                      <message clientCredentialType="Windows" negotiateServiceCredential="true"
                                          algorithmSuite="Default" />
                                  </security>
                              </binding>
                          </wsHttpBinding>
                      </bindings>
                      <client>
                          <endpoint address="http://sh01d.magion.nl:8081/PIWebServices/PITimeSeries.svc"
                              binding="wsHttpBinding" bindingConfiguration="BasicEndpoint"
                              contract="PITimeSeriesRef.IPITimeSeries" name="BasicEndpoint">
                              <identity>
                                  <servicePrincipalName value="HOST/SH01D" />
                              </identity>
                          </endpoint>
                      </client>
                  </system.serviceModel>
              </configuration>

               

               

               

              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>
                  <sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
                    <sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
                      <section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication" />
                      <sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
                        <section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere" />
                        <section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication" />
                        <section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication" />
                        <section name="roleService" type="System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication" />
                      </sectionGroup>
                    </sectionGroup>
                  </sectionGroup>
                  <section name="PIWebServiceSettings" type="System.Configuration.AppSettingsSection, System.Configuration, Version=2.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="Full" />
                </PIWebServiceSettings>
                <appSettings>
                </appSettings>
                <connectionStrings />
                <system.web>
                  <!--
                          Set compilation debug="true" to insert debugging
                          symbols into the compiled page. Because this
                          affects performance, set this value to true only
                          during development.
                      -->
                  <compilation debug="false">
                    <assemblies>
                      <add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
                      <add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
                      <add assembly="System.Configuration.Install, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A" />
                      <add assembly="System.Management, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A" />
                      <add assembly="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
                    </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" />
                  <!--
                          The <customErrors> section enables configuration
                          of what to do if/when an unhandled error occurs
                          during the execution of a request. Specifically,
                          it enables developers to configure html error pages
                          to be displayed in place of a error stack trace.

               

                      <customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
                          <error statusCode="403" redirect="NoAccess.htm" />
                          <error statusCode="404" redirect="FileNotFound.htm" />
                      </customErrors>
                      -->
                  <pages>
                    <controls>
                      <add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
                    </controls>
                  </pages>
                  <httpHandlers>
                    <remove verb="*" path="*.asmx" />
                    <add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
                    <add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
                    <add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" validate="false" />
                  </httpHandlers>
                  <httpModules>
                    <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
                  </httpModules>
                </system.web>
                <system.codedom>
                  <compilers>
                    <compiler language="c#;cs;csharp" extension=".cs" warningLevel="4" type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
                      <providerOption name="CompilerVersion" value="v3.5" />
                      <providerOption name="WarnAsError" value="false" />
                    </compiler>
                  </compilers>
                </system.codedom>
                <!--
                      The system.webServer section is required for running ASP.NET AJAX under Internet
                      Information Services 7.0.  It is not necessary for previous version of IIS.
                  -->
                <system.webServer>
                  <validation validateIntegratedModeConfiguration="false" />
                  <modules>
                    <add name="ScriptModule" preCondition="integratedMode" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
                  </modules>
                  <handlers accessPolicy="Read, Execute, Script">
                    <remove name="WebServiceHandlerFactory-Integrated" />
                    <add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
                    <add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
                    <add name="ScriptResource" preCondition="integratedMode" verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
                  </handlers>
                </system.webServer>
                <system.serviceModel>
                  <bindings>
                    <wsHttpBinding>
                      <binding name="wsBinding" bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288" maxReceivedMessageSize="655360" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
                        <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" />
                        <security mode="Message">
                          <message clientCredentialType="Windows" negotiateServiceCredential="true" algorithmSuite="Default" establishSecurityContext="true" />
                        </security>
                      </binding>
                    </wsHttpBinding>
                    <mexHttpBinding>
                      <binding name="mexBinding" />
                    </mexHttpBinding>
                  </bindings>
                  <services>
                    <service behaviorConfiguration="PIDataService.ServiceBehavior" name="PIWebServices.PIDataService.PITimeSeriesSvcImpl">
                      <endpoint address="mex" binding="mexHttpBinding" name="mexBasicEndpoint" contract="IMetadataExchange" />
                      <endpoint binding="wsHttpBinding" bindingConfiguration="wsBinding" name="BasicEndpoint" bindingNamespace="http://xml.osisoft.com/services/PIDataService" contract="PIWebService.PIDataService.IPITimeSeries">
                        <identity>
                          <servicePrincipalName value="HOST/SH01D" />
                        </identity>
                      </endpoint>
                    </service>
                    <service behaviorConfiguration="PIDataService.PISearchServiceBehavior" name="PIWebServices.PISearchService.PISearchSvcImpl">
                      <endpoint binding="wsHttpBinding" bindingConfiguration="wsBinding" name="SearchEndpoint" bindingNamespace="http://xml.osisoft.com/services/PISearchService" contract="PIWebServices.PISearchService.IPISearch">
                        <identity>
                          <servicePrincipalName value="HOST/SH01D" />
                        </identity>
                      </endpoint>
                      <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
                    </service>
                  </services>
                  <behaviors>
                    <serviceBehaviors>
                      <behavior name="PIDataService.ServiceBehavior">
                        <serviceMetadata httpGetEnabled="true" />
                        <serviceDebug includeExceptionDetailInFaults="true" />
                        <serviceCredentials>
                          <windowsAuthentication includeWindowsGroups="true" allowAnonymousLogons="false" />
                          <issuedTokenAuthentication allowUntrustedRsaIssuers="true" />
                        </serviceCredentials>
                        <serviceAuthorization principalPermissionMode="UseWindowsGroups" impersonateCallerForAllOperations="true" />
                      </behavior>
                      <behavior name="PIDataService.PISearchServiceBehavior">
                        <serviceMetadata httpGetEnabled="true" />
                        <serviceDebug includeExceptionDetailInFaults="true" />
                        <serviceCredentials>
                          <windowsAuthentication includeWindowsGroups="true" allowAnonymousLogons="false" />
                          <issuedTokenAuthentication allowUntrustedRsaIssuers="true" />
                        </serviceCredentials>
                        <serviceAuthorization principalPermissionMode="UseWindowsGroups" impersonateCallerForAllOperations="true" />
                      </behavior>
                    </serviceBehaviors>
                  </behaviors>
                </system.serviceModel>
              </configuration>

                • Re: Error accessing PI Webservice (C#.Net)
                  MvanderVeeken

                  For future reference: please post extensive configuration files like this in an attachment, or use the 'Insert Code' when using 'Use Rich Formatting' when you reply.

                   

                  Ok, so you are using wsHttpBinding. The default security setting for this is using Windows authentication.

                   

                  A few pointers to look at:

                  • Does the user you running your PI Web Services client under have permissions on the server?
                  • Are both machines in a domain? Are they in the same domain? If so, in this case: WCF Windows security means AD authentication.
                  • If they are not part of a domain, you can create a user on the PI Web Services machine with the exact same username and password. If the machines are not part of a domain, WCF Windows security will default to NTLM authentication.

                  If none of this is working, try defaulting your configuration to basicHttpBinding (default is no security) and go from there. You can review the 'PI Web Services User Manual' (available in the Library) for options.

                    • Re: Error accessing PI Webservice (C#.Net)
                      mhamel

                      According to what you've posted, the application you are debugging is not located on the same machine as the PI Server. This will have impacts on how the credentials are passed back to the PI Web Services, PI Server and PI AF Server. By default if you don't override the impersonation level of your client application you will inherit the Identification mode. This will not permit to connect properly to your PI Web Services application in a distributed environment (a.k.a the debugging application is not run on the same machine as the PI Web Services and PI Server). You will need to use a delegation level to function properly in a secured environment.

                       

                      You can control this client behavior by two ways:

                       

                      - Configure the app.config file to add a defined behavior inside the <system.serviceModel> and </system.serviceModel> tags such as the following example: 

                       

                      <behaviors>
                          <endpointBehaviors>
                              <behavior name="ImpersonationLevel">
                                  <clientCredentials>
                                      <windows allowedImpersonationLevel="Delegation" />
                                  </clientCredentials>
                              </behavior>
                         </endpointBehaviors>
                      </behaviors>

                       

                      - Define the client behavior within your code; this is done by setting the AllowedImpersonationLevel property.

                       
                      proxy.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Delegation;
                      

                       

                       

                      Your PI Web Services virtual application on your Web Server (SH01D) must be hosted by an application pool with an account that can impersonate or delegate. Naturally, if you run it as Network Service you are capable of impersonating or delegating but for delegation you will need to change the configuration inside Active Directory to enable that machine (SH01D) to delegate security credentials. If you run the application pool with a domain account (service account for example), you will need to configure the machine for delegation and also enable the account too. These tasks can be done by the domain administrator. Make sure you if you use constrained delegation to choose the w3wp.exe process because this is the process running the application pool with the Web Server you have.

                       

                      I invite you to read the PI Web Services 2010 User Guide in the section Supported Security Configurations to know how it works. If you are more curious about the WCF Security topic, I give you this interesting link at Microsoft.

                        • Re: Error accessing PI Webservice (C#.Net)
                          eweewee

                          Hi Mathieu,

                           

                          thanks for the help. It works fine now.

                           

                          Eugene

                            • Re: Error accessing PI Webservice (C#.Net)
                              DavidMFairchild

                              Hi Mathieu,

                               

                              I am reading over the PI Web Services 2010 R3 Manual, the section on Configuring PI Web Services to use Kerberos Authentication and it's really rather confusing.

                               

                              I have a small network at home with two Windows 2008 R2 servers and one Windows 7 Professional Client.  I have my PI Server and PI AF Server on one of the servers and AD DS, AD CS, DNS, IIS and the PI Web Server on the other server.

                               

                              I have set up Kerberos on the AD because I have a couple of Linux clients that log into this Domain.  I'm learning AD as I go along.

                               

                              I set up a simple WPF application on the client using VS2008 that merely displays a snapshot value from a tag, SINUSOID, at the moment.  I created the class using svcutil.exe and output.config.  Added the class to my project and replaced the contents of the app.config file with the contents of the output.config file.

                               

                              I created a PI-Users Identity on the PI Server and mapped "Domain Users" to PI-Users and

                               

                              The application appears to get through the web server but the PI Server rejects the connection with "Unsuccessful login ID: 59 ... Name: w3wp.exe(3236)remote. Credentials used: IIS APPPOOL\ASP.NET v4.0 DefaultAppPool ...".

                               

                              This appears to be the case of needing a delegation as you mention and I also got from the users guide.  But just how to do that is not well explained at all.

                               

                              Obviously, the IIS service is running under an AppPool.  Some of my questions are:

                               

                              How do I tell if the if the application pool is under a domain account?  And which one?

                               

                              How do I change it to my new account?  (I can't find it in the services dialog app.)

                               

                              The whole explanation on setting up the new account to run IIS under is confusing.  First they associate the new account with the URL of the service.  Then they appear to associate another account with the web server and yet another account with the PI server.  Where are all of these accouts coming from?  How many new accounts do you actually need to create?  They also seem to switch randomly between upper and lower case for the server name.  I thought NetBios used all caps.  Does this matter?

                               

                              How do I mark the domain account I created as trusted for delegation in AD?  I have a wizard under the Domain Controller machine that allows you to delegate control to a user, but I don't think this is the same thing.  I wound up finding the Delegation tab on the user I created and set it to trust for all services.

                               

                              There is no "servicePrincipalName" in web.config in ..\PIPC\PI Web Services.  I probably need to add one somewhere, but I'm not sure where to add it.

                               

                              I, for one, could really use better instructions on what is a very complex subject.

                                • Re: Error accessing PI Webservice (C#.Net)
                                  mhamel

                                  @David: Please find my answers to your questions.

                                   

                                  I would like to clarify your affirmation: "Obviously, the IIS service is running under an AppPool.".  I have added to this post a diagram of the components involved when calling PI Web Services to illustrate the different steps and how the security is handled.

                                   

                                  The facing component of a Web Service with IIS 7.0 and later is the WWW Service; it is running under the LocalSystem account (computer account) generally. The WWW Service will intercept the request and hand it over to the Windows Process Activation Service (WAS) to obtain information form the configuration store to know what to do next. Once the configuration is read and known, this information is handed over back to the WWW Service that will configure the HTTP.sys layer. WAS starts a worker process from the application pool to which the request was made. This worker process executes under a different account which can be a local account such as Network Service account or a domain account. The different configured modules are activated within the worker process. One of them is the PI Web Services module. Thereafter, a call using the request parameters will be sent to either PI Data Archive of PI AF Server using the worker process credentials or impersonated credentials.

                                   

                                  16308-_2D00_-IIS-diagram.png

                                   

                                  1. When a client browser initiates an HTTP request for a resource on the Web server, HTTP.sys intercepts the request.
                                  2. HTTP.sys contacts WAS to obtain information from the configuration store.
                                  3. WAS requests configuration information from the configuration store, applicationHost.config.
                                  4. The WWW Service receives configuration information, such as application pool and site configuration.
                                  5. The WWW Service uses the configuration information to configure HTTP.sys.
                                  6. WAS starts a worker process for the application pool to which the request was made. The required modules defined within the applicationhost.config file will be called. One of them is the PI Web Services module.
                                  7. PI Web Services module is sending a request to either the PI Data Archive (PI or PE path) or PI AF Server (AF path).
                                  8. PI Web Services module receives a response from either the PI Data Archive or PI AF Server, packages the answer as SOAP message and hands over to the worker process.
                                  9. The worker process returns a response to HTTP.sys.
                                  10. The client receives a response.

                                   

                                  I have added answers with a step-by-step approach to your questions too.

                                   

                                  How do I tell if the application pool is under a domain account?  And which one?
                                  You need to open your IIS Manager and click on the Application Pools item on the left end side (See figure 1). You will see in the right pane the list of all your application pools in use. To validate which virtual application is using which application pool you right-click on one of them and pick the option View Applications. You will see a table presenting the virtual path of each application running under this pool (See figure 2).

                                  Figures

                                  16308-_2D00_-sc1.png

                                  Figure 1

                                  16308-_2D00_-sc2.png

                                  Figure 2

                                  16308-_2D00_-sc3.png

                                  Figure 3

                                  16308-_2D00_-sc4.png

                                  Figure 4

                                  16308-_2D00_-sc5.png

                                  Figure 5

                                  16308-_2D00_-sc6.png

                                  Figure 6

                                  How do I change it to my new account?

                                   

                                  From the Application Pools pane, right-click on the pool you want to modify the configuration and choose the option Advanced Settings. (See figure 3). Locate the Identity attribute under the Process Model category. By default this value is set to ApplicationPoolIdentity. Click on the select (ellipsis) button, this will bring a dialog box to choose built-in or custom account (See figure 4). Click on Custom account and enter the credentials of the domain account you want to use (See figure 5 and 6).

                                   

                                  Where are all of these accounts coming from? How many new accounts do you actually need to create?
                                  What you will the most, is three layers: IIS, ASP.NET and WCF. You can specify accounts and configuration on each layer. You have also the application pools that work as a host of your virtual application that have an account also. Application pools are used to create separation between your applications for different reasons such as:

                                  • Create hermetic security zone
                                  • Use different .NET Framework
                                  • Allow different security levels
                                  • Allow different configurations or allocation of resources on the Web Server
                                  • Etc.

                                  If you need to configure PI Web Services to pass the credentials of the original caller, you will need:

                                   

                                  - Authorize Windows Authentication under the IIS\Authentication section of PI Web Services
                                  - Use the web_config_wsHttp.config file under C:\Inetpub\wwwroot\PIWebServices\Help\Samples as an example to create your web.config file. It contains all you need for a default windows security binding.
                                  - Change the servicePrincipalName attribute by changing the web_server_machine_name value by the name of your Web Server. This is done within the web.config file. I have put an excerpt of my configuration below.

                                   

                                  <services>
                                      <service behaviorConfiguration="PIDataService.PITimeSeriesServiceBehavior" name="PIWebServices.PIDataService.PITimeSeriesSvcImpl">
                                          <endpoint address="mex" binding="mexHttpBinding" name="mexBasicEndpoint" contract="IMetadataExchange" />
                                          <endpoint binding="wsHttpBinding" bindingConfiguration="wsConfig" name="BasicEndpoint" bindingNamespace="
                                  http://xml.osisoft.com/services/PIDataService" contract="PIWebService.PIDataService.IPITimeSeries">
                                          <identity>
                                              <servicePrincipalName value="HOST/PISILVER" />
                                          </identity>
                                       </endpoint> 
                                  </services>

                                   

                                  - You will need that the Web Server has Kerberos Delegation capability in Active Directory if you are running under the Network Service account, or if you are running under a domain account instead, you will need also to enable Delegation privilege under the domain account.
                                  - Set the proper security for the PI Data Archive or PI AF Server

                                   


                                  How do I mark the domain account I created as trusted for delegation in AD?
                                  I suggest your visit this link from Microsoft TechNet to know how.

                                   

                                  Links

                                   

                                  If you want to learn more on IIS architecture, I suggest you this link, for WCF security you can use this link.

                                   

                                  I have already mentionned it within another thread but I am recalling it here too. We have something we would like to start soon regarding a white paper on security practices around WCF. We would like to make it a community-driven project, so we can address your concerns, your problems when it comes the time to architecture, configure and test project around WCF.