Authentication¶
New in version 0.5.
django-modern-rpc supports authentication. It is possible to restrict access to any RPC method depending on conditions named “predicate”.
Basics¶
To provide authentication features, django-modern-rpc introduce concept of “predicate”. It is a python function taking a request as argument and returning a boolean:
def forbid_bots_access(request):
forbidden_bots = [
'Googlebot', # Google
'Bingbot', # Microsoft
'Slurp', # Yahoo
'DuckDuckBot', # DuckDuckGo
'Baiduspider', # Baidu
'YandexBot', # Yandex
'facebot', # Facebook
]
incoming_UA = request.META.get('HTTP_USER_AGENT')
if not incoming_UA:
return False
for bot_ua in forbidden_bots:
# If we detect the caller is one of the bots listed above...
if bot_ua.lower() in incoming_UA.lower():
# ... forbid access
return False
# In all other cases, allow access
return True
It is associated with RPC method using @set_authentication_predicate
decorator.
from modernrpc.core import rpc_method
from modernrpc.auth import set_authentication_predicate
from myproject.myapp.auth import forbid_bots_access
@rpc_method
@set_authentication_predicate(forbid_bots_access)
def my_rpc_method(a, b):
return a + b
Now, the RPC method becomes unavailable to callers if User-Agent is not provided or if it has an invalid value.
In addition, you can provide arguments to your predicate using params
:
@rpc_method
@set_authentication_predicate(my_predicate_with_params, params=('param_1', 42))
def my_rpc_method(a, b):
return a + b
It is possible to declare multiple predicates for a single method. In such case, all predicates must return True to allow access to the method.
@rpc_method
@set_authentication_predicate(forbid_bots_access)
@set_authentication_predicate(my_predicate_with_params, params=('param_1', 42))
def my_rpc_method(a, b):
return a + b
HTTP Basic Authentication support¶
django-modern-rpc comes with a builtin support for HTTP Basic Auth. It provides a set of decorators to directly extract user information from request, and test this user against Django authentication system:
from modernrpc.auth.basic import http_basic_auth_login_required, http_basic_auth_superuser_required, \
http_basic_auth_permissions_required, http_basic_auth_any_of_permissions_required, \
http_basic_auth_group_member_required, http_basic_auth_all_groups_member_required
from modernrpc.core import rpc_method
@rpc_method
@http_basic_auth_login_required
def logged_user_required(x):
"""Access allowed only to logged users"""
return x
@rpc_method
@http_basic_auth_superuser_required
def logged_superuser_required(x):
"""Access allowed only to superusers"""
return x
@rpc_method
@http_basic_auth_permissions_required(permissions='auth.delete_user')
def delete_user_perm_required(x):
"""Access allowed only to users with specified permission"""
return x
@rpc_method
@http_basic_auth_any_of_permissions_required(permissions=['auth.add_user', 'auth.change_user'])
def any_permission_required(x):
"""Access allowed only to users with at least 1 of the specified permissions"""
return x
@rpc_method
@http_basic_auth_permissions_required(permissions=['auth.add_user', 'auth.change_user'])
def all_permissions_required(x):
"""Access allowed only to users with all the specified permissions"""
return x
@rpc_method
@http_basic_auth_group_member_required(groups='A')
def in_group_A_required(x):
"""Access allowed only to users contained in specified group"""
return x
@rpc_method
@http_basic_auth_group_member_required(groups=['A', 'B'])
def in_group_A_or_B_required(x):
"""Access allowed only to users contained in at least 1 of the specified group"""
return x
@rpc_method
@http_basic_auth_all_groups_member_required(groups=['A', 'B'])
def in_groups_A_and_B_required_alt(x):
"""Access allowed only to users contained in all the specified group"""
return x