15 Replies Latest reply on Feb 9, 2017 10:18 AM by gregor

    Accessing PIWebAPI from Python outside domain

    Nocodes79

      Hi all,

       

      I was wondering if there is anybody who has a working example of Python connecting to PIWebAPI working with kerberos authentication (using requests-kerberos helper) from a machine which is outside the PI Web API domain.

       

      I mean, I have tried using principal="user@REALM:password" to force explicit login (I am in a Windows machine), but I keep getting a 401 error.

       

      Just to be sure, is REALM to use the typical Windows realm? For example my INDRA domain translates to INDRA.ES. i.e. the realm I get launching %USERDNSDOMAIN% from an MS-DOS prompt

        • Re: Accessing PIWebAPI from Python outside domain
          Marcos Vainer Loeff

          Hi Nicola,

           

          If you want to use Kerberos, the client needs to communicate with the Domain Controller from the domain. If it is outside the domain, this won't happen. Why don't you use Basic Authentication instead?

            • Re: Accessing PIWebAPI from Python outside domain
              Nocodes79

              Hi Marcos,

               

              switching to Basic would be the next step. But now I have a question.

              Now I can access the PIWebAPI using Chrome, so why can't I access it from my Python app?

              I checked and the PIWebAPI instance only supports kerberos.

               

              On the other hand, could enabling Basic and Kerberos an the PIWebAPI be a problem for the Coresight instance that reads through this instance of PIWebAPI?

                • Re: Accessing PIWebAPI from Python outside domain
                  rsun

                  you could troubleshoot your http request using Fiddler. Also, I would suggest to change AuthenticationMethods to Anonymous, CoresHeaders, CorsMethods, CorsOrigins to *. this is to make sure your app is able to work before tightening security.

                  Capture.JPG

                    • Re: Accessing PIWebAPI from Python outside domain
                      Nocodes79

                      Hi Ricky,

                      thanks for the suggestions. I cannot use Fiddler as it doesn't allow (as long as I know) entering a principal different from the one of the user who is running the application.

                       

                      Another thing, editing CORS could solve some issues, but, just for curiosity, why can I access it using Chrome?

                        • Re: Accessing PIWebAPI from Python outside domain
                          Rhys Kirk

                          Nicola Gargano wrote:

                          but, just for curiosity, why can I access it using Chrome?

                          Your web credentials might be cached for PI Coresight... "Control Panel => User Accounts => Credential Manager"

                          • Re: Accessing PIWebAPI from Python outside domain
                            gregor

                            Hi Nicola,

                             

                            Ricky Sun

                            suggestion regarding Fiddler was not intended to change the credentials but for monitoring / troubleshooting what credentials are actually used.

                             

                            As mentioned by Marcos Vainer Loeff, Kerberos requires you to operate in a domain environment. When using Chrome on a client that is not a domain member, you will be prompted for credentials. Entering valid domain credentials will allow you to connect but as you can see from the Security Event Log on the PI Web API host, security falls back to NTLM. This will not work using Python, at least not as far as I know and as indicated by the 401 error that you are seeing.

                             

                            The remaining authentication options for you are Anonymous and Basic. PI Web API Crawler service however requires Kerberos. When you like to execute queries against Index Search, the only solution I am aware of is installing a primary PI Web API instance with Kerberos authentication and a second instance with Basic or Anonymous on a separate host. When installing the secondary instance, you refer the UNC path to Index Search Crawler files of the Primary instance.

                             

                            Please note that the Indexed Search functionality is currently in CTP (Community Technology Preview state and refer to Indexed Search Shared Index CTP White Paper for more information.

                            2 of 2 people found this helpful
                              • Re: Accessing PIWebAPI from Python outside domain
                                Nocodes79

                                Thanks for the explanation Gregor!

                                My next question, would be, why NTLM fallback does not occurr with Python kerberos?

                                Well, I will leave the question here if anybody has an answer...

                                  • Re: Accessing PIWebAPI from Python outside domain
                                    Nocodes79

                                    Thanks to Gregor Beck's hint I have got it working. Just used the package requests-ntlm and, at least, it connects. Now we will see if we face any problem.

                                    1 of 1 people found this helpful
                                      • Re: Accessing PIWebAPI from Python outside domain
                                        gregor

                                        Hello Nicola,

                                         

                                        That's great news and a valuable hint. Thanks for sharing. Would you also be willing to share a complete script that can be used to fire a query against PI Web API?

                                        Please allow me to remember, you can verify with the Security Event Log on the PI Web API host what security is used.

                                          • Re: Accessing PIWebAPI from Python outside domain
                                            Nocodes79

                                            Hi Gregor,

                                             

                                            here is the snippet. I cannot easily acces the PIWebAPI server, so I will suppose it connects using NTLM. The code just connects and then gets the https://<piwebapi_server>/piwebapi resources.

                                            import requests
                                            import base64
                                            import datetime
                                            import time
                                            from requests_ntlm import HttpNtlmAuth
                                            
                                            
                                                def _init_pi_servers(self):
                                                    """
                                                    Get PI servers urls
                                                    Pi servers could be:
                                                        Self
                                                        AssetServers
                                                        DataServers
                                                        Search
                                                        System
                                                    """
                                                    self._m_pi_servers = {}
                                                    url = '{0}/piwebapi'.format(self._m_server)
                                                    ntlm_auth = HttpNtlmAuth('{0}\\{1}'.format(self._m_pi_realm, self._m_pi_user), self._m_pi_pass)
                                                    r = requests.get(url=url, auth=ntlm_auth, verify=False)
                                                    if r.status_code != 200:
                                                        print("ERROR: Code: {0}: {1}".format(r.status_code, r.text))
                                                        return
                                            
                                            
                                                    ret = r.json()
                                                    for k, v in ret.get('Links', {}).items():
                                                        self._m_pi_servers[k] = v
                                            
                                            
                                                    print(self._m_pi_servers)
                                            
                                            1 of 1 people found this helpful
                                      • Re: Accessing PIWebAPI from Python outside domain
                                        asorokina

                                        Minor clarification: the PI Indexed Search functionality was released with the first version of PI Web API. What is currently in CTP is the Shared Index feature of the Indexed Search. 

                                        2 of 2 people found this helpful
                              • Re: Accessing PIWebAPI from Python outside domain
                                rsun

                                Hi Nicola, If fiddler is not an option, try postman for chrome. You will need a http request tool to troubleshoot this. chrome browser may already have integrated windows security or have saved the password. Testing with the browser won't give you the full picture. Thanks Ricky