authentication.py 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. from __future__ import unicode_literals
  2. import base64
  3. from rest_framework import exceptions, HTTP_HEADER_ENCODING
  4. from rest_framework.authtoken.models import Token
  5. from rest_framework.authentication import BaseAuthentication, get_authorization_header, authenticate
  6. class BasicTokenAuthentication(BaseAuthentication):
  7. """
  8. HTTP Basic authentication that uses username and token.
  9. Clients should authenticate by passing the username and the token as a
  10. password in the "Authorization" HTTP header, according to the HTTP
  11. Basic Authentication Scheme
  12. Authorization: Basic dXNlcm5hbWU6dG9rZW4=
  13. For username "username" and password "token".
  14. """
  15. model = Token
  16. """
  17. A custom token model may be used, but must have the following properties.
  18. * key -- The string identifying the token
  19. * user -- The user to which the token belongs
  20. """
  21. def authenticate(self, request):
  22. auth = get_authorization_header(request).split()
  23. if not auth or auth[0].lower() != b'basic':
  24. return None
  25. if len(auth) == 1:
  26. msg = 'Invalid basic auth token header. No credentials provided.'
  27. raise exceptions.AuthenticationFailed(msg)
  28. elif len(auth) > 2:
  29. msg = 'Invalid basic auth token header. Basic authentication string should not contain spaces.'
  30. raise exceptions.AuthenticationFailed(msg)
  31. return self.authenticate_credentials(auth[1])
  32. def authenticate_credentials(self, basic):
  33. try:
  34. user, key = base64.b64decode(basic).decode(HTTP_HEADER_ENCODING).split(':')
  35. token = self.model.objects.get(key=key)
  36. except self.model.DoesNotExist:
  37. raise exceptions.AuthenticationFailed('Invalid basic auth token')
  38. if not token.user.is_active:
  39. raise exceptions.AuthenticationFailed('User inactive or deleted')
  40. return token.user, token
  41. def authenticate_header(self, request):
  42. return 'Basic'
  43. class URLParamAuthentication(BaseAuthentication):
  44. """
  45. Authentication against username/password as provided in URL parameters.
  46. """
  47. model = Token
  48. def authenticate(self, request):
  49. """
  50. Returns a `User` if a correct username and password have been supplied
  51. using URL parameters. Otherwise returns `None`.
  52. """
  53. if not 'username' in request.QUERY_PARAMS:
  54. msg = 'No username URL parameter provided.'
  55. raise exceptions.AuthenticationFailed(msg)
  56. if not 'password' in request.QUERY_PARAMS:
  57. msg = 'No password URL parameter provided.'
  58. raise exceptions.AuthenticationFailed(msg)
  59. return self.authenticate_credentials(request.QUERY_PARAMS['username'], request.QUERY_PARAMS['password'])
  60. def authenticate_credentials(self, userid, key):
  61. try:
  62. token = self.model.objects.get(key=key)
  63. except self.model.DoesNotExist:
  64. raise exceptions.AuthenticationFailed('Invalid token')
  65. if not token.user.is_active:
  66. raise exceptions.AuthenticationFailed('User inactive or deleted')
  67. return token.user, token