Re: Basic Authentication in the header - Authorization : Basic <key>

ElliotB <[email protected]> Wed, 11 Apr 2018 11:45:42 -0700 (PDT)
Newsgroups gmane.comp.python.cherrypy
Message-ID <[email protected]>
Perfect!!!!

Thanks so very much, Björn.  This is working for me perfectly.  Very much 
appreciated.

On Wednesday, April 11, 2018 at 1:43:56 AM UTC-4, Björn Pedersen wrote:
>
> import cherrypy
>
> def check_auth():
>   needs_auth = cherrypy.request.config.get('auth.require', False)
>   if needs_auth and not cherrypy.request.headers.get('X-HTTP-APIKEY', None
> ) =="1234":
>      raise cherrypy.HTTPError(401)
>
>
> cherrypy.tools.auth = cherrypy.Tool('before_handler', check_auth, priority
> =50)
>
>
> def needsauth():
>     '''A decorator that sets auth.require config
>     variable.'''
>
>     def decorate(f):
>         if not hasattr(f, '_cp_config'):
>             f._cp_config = dict()
>         if 'auth.require' not in f._cp_config:
>             f._cp_config['auth.require'] = []
>         f._cp_config['auth.require'] = True
>         return f
>
>     return decorate
>
>
> class main(object):
>     _cp_config = {'tools.auth.on': True,}
>     @cherrypy.expose
>     @needsauth()
>     def myfunction(self):
>         print 1
>         return '<html>Hi</html>'
>
> cherrypy.quickstart(main())
>
>
>
>
>
>
> Am Dienstag, 10. April 2018 21:44:19 UTC+2 schrieb ElliotB:
>>
>> Thanks for that, Björn, however, I'm not sure if the decorator is fully 
>> working.  Can you try it yourself?  I added a function to the above code:
>>     def generate(self, length=8):
>>       print("in the function called generate now, past security" )
>>       return ''.join(random.sample(string.hexdigits, int(length)))
>>
>> Then, whenI assure there is **NO** header set (see Postman screenshot) 
>> the request goes through without violating the authentication of the 
>> string which is '12345'
>>
>> I don't believe the function check_auth is called.  I do see that the two 
>> functions, needsauth and decorate are indeed called.
>> Again, sorry, but can you test the code yourself (see prior posts) and 
>> let me know if you can run it with and without a header with a key 
>> of X-HTTP-APIKEY and a value of 12345?
>> I'd like to see if the two conditions, validated and unvalidated can be 
>> shown.
>> thanks
>>
>> On Monday, April 9, 2018 at 10:09:29 AM UTC-4, Björn Pedersen wrote:
>>>
>>> Im fault,
>>>
>>> it should habe been 
>>> @needsauth()  (and no dummy arg)
>>>
>>> Björn
>>>
>>> Am Freitag, 6. April 2018 05:43:49 UTC+2 schrieb ElliotB:
>>>>
>>>> Björn
>>>> Thanks for the quick reply.  However, Björn, I set up 'quickstart' and 
>>>> implemented your code example and had two situations.
>>>> 1. if the needsauth function does not have a single parameter, Cherrypy 
>>>> returns this:
>>>>         class HelloWorld(object):
>>>>               File "/Volumes/NAOMI 
>>>> PIX/Caremarkets/Cherrypy/Authentication.py", line 36, in HelloWorld
>>>>               @needsauth
>>>>         TypeError: needsauth() takes 0 positional arguments but 1 was 
>>>> given
>>>>
>>>> So, at this time, I simply put in a dummy argument.!!!??!?!?
>>>>
>>>> 2. With the dummy argument in the needsauth function, when running this 
>>>> code below, I am rewarded with this traceback:
>>>>    upon running the following     :   
>>>>
>>>>               http://locahost:8080/myfun
>>>>
>>>>
>>>> 500 Internal Server Error
>>>>
>>>> The server encountered an unexpected condition which prevented it from 
>>>> fulfilling the request.
>>>>
>>>> Traceback (most recent call last):
>>>>   File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/cherrypy/_cprequest.py", line 631, in respond
>>>>     self._do_respond(path_info)
>>>>   File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/cherrypy/_cprequest.py", line 690, in _do_respond
>>>>     response.body = self.handler()
>>>>   File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/cherrypy/lib/encoding.py", line 264, in __call__
>>>>     ct.params['charset'] = self.find_acceptable_charset()
>>>>   File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/cherrypy/lib/encoding.py", line 173, in find_acceptable_charset
>>>>     if encoder(self.default_encoding):
>>>>   File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/cherrypy/lib/encoding.py", line 114, in encode_string
>>>>     for chunk in self.body:
>>>> TypeError: 'HelloWorld' object is not iterable
>>>>
>>>> Powered by CherryPy 14.0.0 <http://www.cherrypy.org/>
>>>>
>>>>
>>>> My code now:
>>>>
>>>> import cherrypy
>>>>
>>>>
>>>> class HelloWorld(object):
>>>>     @cherrypy.expose
>>>>     
>>>>     def index(self):
>>>>         return "Hello world!"
>>>>
>>>>  
>>>>
>>>>     def check_auth():
>>>>       needs_auth = cherrypy.request.config.get('auth.require', False)
>>>>       print ("in check_auth")
>>>>       if needs_auth and not 
>>>> cherrypy.request.header.get('X-HTTP-APIKEY', None) == '12345':
>>>>          raise cherrypy.HTTPError(404) 
>>>>
>>>>     cherrypy.tools.auth = cherrypy.Tool('before_handler', check_auth, 
>>>> priority=50)
>>>>
>>>>     def needsauth(dummy):      #  if I don't put in a parameter:
>>>>         """
>>>>
>>>>                   class HelloWorld(object):
>>>>               File "/Volumes/NAOMI 
>>>> PIX/Caremarkets/Cherrypy/Authentication.py", line 36, in HelloWorld
>>>>               @needsauth
>>>>         TypeError: needsauth() takes 0 positional arguments but 1 was 
>>>> given
>>>>
>>>>         """
>>>>         '''A decorator that sets auth.require config
>>>>         variable.'''
>>>>         print("in needsauth")
>>>>
>>>>         def decorate(f):
>>>>             if not hasattr(f, '_cp_config'):
>>>>                 f._cp_config = dict()
>>>>             if 'auth.require' not in f._cp_config:
>>>>                 f._cp_config['auth.require'] = []
>>>>             f._cp_config['auth.require'] = True
>>>>             return f
>>>>
>>>>         return decorate
>>>>
>>>>     @cherrypy.expose
>>>>     @needsauth
>>>>     def myfun():
>>>>       print("in myfunction now, past security")
>>>>       return
>>>>
>>>>     @cherrypy.expose
>>>>     def stop(self):
>>>>         """
>>>>         Stop the server
>>>>         """
>>>>         cherrypy.engine.exit()
>>>>         cherrypy.engine.stop()
>>>>
>>>>
>>>> if __name__ == '__main__':
>>>>
>>>>     cherrypy.server.socket_host = '0.0.0.0' # put it here 
>>>>     cherrypy.quickstart(HelloWorld(), '/')
>>>>
>>>>
>>>>   - - - - - - - -
>>>>
>>>>
>>>> Ideas?  Again, really new to Cherrypy so your help is much appreciated.
>>>>
>>>> Thanks
>>>>
>>>>
>>>>
>>>> On Thursday, April 5, 2018 at 5:21:02 AM UTC-4, Björn Pedersen wrote:
>>>>>
>>>>> Hi, 
>>>>>
>>>>> I would not recommend to mix API-Key auth and Basic Auth. 
>>>>> Send it as e.g X-HTTP-APIKEY header, and in your handler function (or 
>>>>> some tool function) 
>>>>> inspect cherrypy.request.header
>>>>>
>>>>> using a tool function:
>>>>>
>>>>>
>>>>> def check_auth():
>>>>>   needs_auth = cherrypy.request.config.get('auth.require', False)
>>>>>   if needs_auth and not cherrypy.request.header.get('X-HTTP-APIKEY', 
>>>>> None) == <your key here>:
>>>>>      raise cherrypy.HTTPError(404) 
>>>>>
>>>>> cherrypy.tools.auth = cherrypy.Tool('before_handler', check_auth, 
>>>>> priority=50)
>>>>>
>>>>> def needsauth():
>>>>>     '''A decorator that sets auth.require config
>>>>>     variable.'''
>>>>>
>>>>>     def decorate(f):
>>>>>         if not hasattr(f, '_cp_config'):
>>>>>             f._cp_config = dict()
>>>>>         if 'auth.require' not in f._cp_config:
>>>>>             f._cp_config['auth.require'] = []
>>>>>         f._cp_config['auth.require'] = True
>>>>>         return f
>>>>>
>>>>>     return decorate
>>>>>
>>>>> @cherrypy.expose
>>>>> @needsauth
>>>>> def myfunction(....):
>>>>>   .....
>>>>>
>>>>>
>>>>> Björn
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> Am Donnerstag, 5. April 2018 08:14:06 UTC+2 schrieb ElliotB:
>>>>>>
>>>>>> I've reviewed the documentation at 
>>>>>> http://cherrypy.readthedocs.io/en/latest/basics.html#authentication in 
>>>>>> order to understand how to send my API call to Cherrypy and validate an API 
>>>>>> key that I'll have in the header of the HTTP request that I'll send from my 
>>>>>> client side program. The header will follow Basic Authorization with the 
>>>>>> header having the following example key and value Example: Authorization: 
>>>>>> Basic YWxhZGRpbjpvcGVuc2VzYW1l
>>>>>>
>>>>>> Then I want the Cherrypy function that I write to run only after some 
>>>>>> authorization has be completed. From the client, I'll call my function 
>>>>>> like: https:///myfunction?param1=value&param2=value&param3=value with the 
>>>>>> Basic Authorization header set up as seen above
>>>>>>
>>>>>> and in Cherrypy I'll code the function like:
>>>>>>
>>>>>>  @cherrypy.expose
>>>>>>     def myfunction(self, param1=1,param2=cat,param3=dog):
>>>>>>             # do my work in the function 
>>>>>>         return 
>>>>>>
>>>>>> Note: the function will not have a user enter any credentials. The 
>>>>>> call will pre-populate the basic authorization header programmatically.
>>>>>>
>>>>>> Can you set up the Cherrypy code example in such a way to explicitly 
>>>>>> show me how this can be achieved. Assume a beginner with Cherrypy (e.g. did 
>>>>>> the first 5 or so tutorials only ( 
>>>>>> http://docs.cherrypy.org/en/latest/tutorials.html#tutorials ). 
>>>>>> Thanks much.
>>>>>>
>>>>>>

-- 
You received this message because you are subscribed to the Google Groups "cherrypy-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cherrypy-users+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/[email protected]
To post to this group, send email to cherrypy-users-/JYPxA39Uh5TLH3MbocFF+G/[email protected]
Visit this group at https://groups.google.com/group/cherrypy-users.
For more options, visit https://groups.google.com/d/optout.