How to restrict access to a public webservice using a key?

142 views
Skip to first unread message

Lisandro

unread,
Sep 28, 2016, 7:57:59 AM9/28/16
to web2py-users
Hi there!
I have a web2py app that implements a JSON-RPC public webservice, over HTTPS.
It's public as it doesn't require user and password to authenticate.

However, the webservice is only consumed by a set of other applications that I manage.
So I would like those apps to use a key in order to connect to the webservice.
I'm trying to do such thing with a custom decorator, but I can't make it work.

This is what I have:

from gluon.tools import Service


service
= Service()


def validate_key():
   
return True


@auth.requires(lambda: validate_key())
def call():
    session
.forget()
   
return service()


@service.jsonrpc
def test():
   
return 'test ok'



But when I try to connect to the webservice, I receive this error:
ProtocolError: <ProtocolError for dev.medios/ws/call/jsonrpc: 303 SEE OTHER>

I'm not sure if what I'm tying to do is possible in that way. 
I know that I can apply the @auth.requires_login() decorator to the call() method, but that would force me to create users for every app using the webservice, and that's not wat I want. I would like to simply generate a key for every app that needs to use the webservice, and then ask the applications to use that key (either in the call to connect to the webservice, or in every call to any method of the webservice).

What would be the correct approach?
Thanks in advance.
Regards, 
Lisandro.

Marlysson Silva

unread,
Sep 28, 2016, 8:15:19 AM9/28/16
to web2py-users
This is what you need:


Json Web Token , communications to services "rest" .. I think that facilitates your work

Niphlod

unread,
Sep 28, 2016, 5:42:04 PM9/28/16
to web2py-users
jwt is the emerging standard for apis and such, but if the usage is all-internal, why don't you just start simple and do


if request.vars.token not in ('aaaaxa', 'bbbbbbxb', 'cccccc'):
     raise HTTP(403)

 ?

Lisandro

unread,
Sep 29, 2016, 9:28:05 AM9/29/16
to web2py-users
Thanks Niphlod, nice and clean solution. 
I was trying to just that, but I was trying to validate that token using the decorator @auth.requires(lambda: validate_token()) for the call() method, but it always returned a 303 code. I also tried with a custom decorator, with no luck.
Anyway, your suggested solution is more than enough for me, so I'll proceed with that.

Thank you both for your time!

Best regards,
Lisandro.

Niphlod

unread,
Sep 29, 2016, 4:06:19 PM9/29/16
to web2py-users
everything in auth has underlying defaults to have an entity (usually, the user) to authenticate. if it's not authenticated, then it's usually redirected to the login page. see auth.requires signature in deep if you want to use it as a standard "block this if this condition isn't met" style-decorator.
Reply all
Reply to author
Forward
0 new messages