简体   繁体   中英

Mixing Authentication Policies in Pyramid

I am writing an application that will have some HTML content (display tables etc.) and also have a JSON API.

For normal HTML I use AuthTktAuthenticationPolicy for authentication and ACLAuthorizationPolicy for authorization. So the user is presented with a login form and on successful login auth_tkt cookie is set. The system works fine.

Now I want to replicate a similar system for JSON API. The problem is that for API requests user will not necessarily be logged in. So each request requires an api_key parameter. Based on the key, if I find a valid user, I send back the JSON. Otherwsie I display a 403 page.

One way is to do this in each view

api_key = request.GET.get('api_key',None)
user = FrontEndUsers.User_by_api_key(api_key)
if user: 
    #Process view
else:
    return HTTPForbidden

However, it seems too much of a boiler-plate to use for each view to do exaclty what an authentication policy would do. Can I specify a separate authentication policy for JSON routes? Or is there any other way of doing this?

EDIT

On second thoughts it seems that even with AuthTktAuthenticationPolicy , I have to do security.authenticated_userid() in every view (If I need authentication info). This I have already factored into a separate function

def get_auth_info(): 
    user_id = security.authenticated_userid()
    login_info = {}
    if user_id is not None: 
        login_info['login'] = True
        login_info['logged_in_user'] = FrontendUsers.get_user_by_id(user_id).name
    else: 
        login_info['login'] = False
    return login_info

I can include the API_key check function call in this function so that none of my views change (I still only call get_auth_info() ) and yet I can check if correct API key has been presented.

I'd still like to see if there are any other ways to do this or if there's a problem with my current scheme

You didn't mention anywhere in here how you're using permissions? Proper usage of permissions and ACLs on your views should prevent you from needing to run that boilerplate at the start of your function. For the simple paste you showed, you simply need a permission='logged_in' and an ACE mapping (Allow, Authenticated, 'logged_in') , but of course you can get more complex if necessary.

It is not possible to specify different authentication policies for different views in a simple way because authentication policies in pyramid are intended to be global. You can do it globally via the pyramid_multiauth. Or you may write your own policy that wraps multiple policies and dispatches to one or another depending on request properties.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM