Open bpsgit opened 6 years ago
@bpsgit did you ever figure this out?
I just figured out how to use it with the OAuthResourceOwnerPassword grant type... I needed to implement a CustomOAuth2Validator, and override the proper method for the login validation used by the grant type... There was one major gotcha, OAuthLib/OAuthToolkit have a different request class than django that doesnt have META, so I needed to shim that... and I also needed to figure out which errors to raise by looking at the method in the GrantType that was calling the Validator.validate_user... If you're working with another grant type, you'll probably need to shim a different method.
Hope this helps.
from defender.utils import add_login_attempt_to_db, check_request, is_already_locked
from django.contrib.auth import authenticate
from oauth2_provider.oauth2_validators import OAuth2Validator
from oauthlib.oauth2.rfc6749 import errors
class CustomOAuth2Validator(OAuth2Validator):
# this method is called by oauthlib.oauth2.rfc6749.grant_types.ResourceOwnerPasswordCredentialsGrant
# it looks like that is the only grant type that calls this method.
def validate_user(self, username, password, client, request, *args, **kwargs):
"""
Check username and password correspond to a valid and active User,
enforce django defender on authentication.
"""
# django-defender expects https://docs.djangoproject.com/en/3.2/ref/request-response/#django.http.HttpRequest.META
# but OAuthLib.core.Request makes a simplified version without META
# so we need to shim it here to make defender happy.
request.META = request.headers
locked = is_already_locked(request, username=username)
# print('locked', locked)
# print('request', request)
# print('request', request.body)
if locked:
raise errors.InvalidGrantError(description='Too many failed login attempts.', status_code=403, request=request)
u = authenticate(username=username, password=password)
login_valid = u is not None and u.is_active
add_login_attempt_to_db(request, login_valid=login_valid, username=username)
check_request(request, login_unsuccessful=not login_valid, username=username)
if not login_valid:
raise errors.InvalidGrantError('Invalid credentials given.', status_code=401, request=request)
request.user = u
return login_valid
Hi,
Trying to use with OAUTH2 - django-oauth-toolkit.
MIDDLEWARE_CLASSES = ( 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'oauth2_provider.middleware.OAuth2TokenMiddleware', 'defender.middleware.FailedLoginMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.security.SecurityMiddleware', ) User blocking works fine in case of post on /admin/login/ Does not work on /accounts/login/
Thanks in advance.