From 713d15297c37103ed584b1a31e1e341888c534c5 Mon Sep 17 00:00:00 2001 From: Andy Clayton Date: Wed, 22 Nov 2017 11:40:58 -0600 Subject: [PATCH] include request in password grant authenticate call An an example this can be used to help implement measures against brute force attacks and to alert on or mitigate other untrusted authentication attempts. --- oidc_provider/lib/endpoints/token.py | 8 ++++++++ oidc_provider/tests/app/utils.py | 11 +++++++++++ oidc_provider/tests/cases/test_token_endpoint.py | 12 ++++++++++++ 3 files changed, 31 insertions(+) diff --git a/oidc_provider/lib/endpoints/token.py b/oidc_provider/lib/endpoints/token.py index c6b96b0..8c32046 100644 --- a/oidc_provider/lib/endpoints/token.py +++ b/oidc_provider/lib/endpoints/token.py @@ -1,3 +1,4 @@ +import inspect from base64 import urlsafe_b64encode import hashlib import logging @@ -96,7 +97,14 @@ class TokenEndpoint(object): if not settings.get('OIDC_GRANT_TYPE_PASSWORD_ENABLE'): raise TokenError('unsupported_grant_type') + auth_args = (self.request,) + try: + inspect.getcallargs(authenticate, *auth_args) + except TypeError: + auth_args = () + user = authenticate( + *auth_args, username=self.params['username'], password=self.params['password'] ) diff --git a/oidc_provider/tests/app/utils.py b/oidc_provider/tests/app/utils.py index fdee81c..457757d 100644 --- a/oidc_provider/tests/app/utils.py +++ b/oidc_provider/tests/app/utils.py @@ -1,5 +1,9 @@ import random import string + +import django +from django.contrib.auth.backends import ModelBackend + try: from urlparse import parse_qs, urlsplit except ImportError: @@ -131,3 +135,10 @@ def fake_idtoken_processing_hook2(id_token, user): def fake_introspection_processing_hook(response_dict, client, id_token): response_dict['test_introspection_processing_hook'] = FAKE_RANDOM_STRING return response_dict + + +class TestAuthBackend: + def authenticate(self, *args, **kwargs): + if django.VERSION[0] >= 2 or (django.VERSION[0] == 1 and django.VERSION[1] >= 11): + assert len(args) > 0 and args[0] + return ModelBackend().authenticate(*args, **kwargs) diff --git a/oidc_provider/tests/cases/test_token_endpoint.py b/oidc_provider/tests/cases/test_token_endpoint.py index 5c787b3..0646046 100644 --- a/oidc_provider/tests/cases/test_token_endpoint.py +++ b/oidc_provider/tests/cases/test_token_endpoint.py @@ -3,6 +3,7 @@ import time import uuid from base64 import b64encode + try: from urllib.parse import urlencode except ImportError: @@ -256,6 +257,17 @@ class TokenTestCase(TestCase): else: self.assertNotIn(claim, userinfo) + @override_settings(OIDC_GRANT_TYPE_PASSWORD_ENABLE=True, + AUTHENTICATION_BACKENDS=("oidc_provider.tests.app.utils.TestAuthBackend",)) + def test_password_grant_passes_request_to_backend(self): + response = self._post_request( + post_data=self._password_grant_post_data(), + extras=self._password_grant_auth_header() + ) + + response_dict = json.loads(response.content.decode('utf-8')) + self.assertIn('access_token', response_dict) + @override_settings(OIDC_TOKEN_EXPIRE=720) def test_authorization_code(self): """