mirror of
https://github.com/jumpserver/jumpserver.git
synced 2026-07-11 09:25:03 +00:00
perf: OAuth2 authentication supports state security parameters.
This commit is contained in:
@@ -69,13 +69,25 @@ class OAuth2Backend(RedirectAuthBackend):
|
||||
response_data = response_data['data']
|
||||
return response_data
|
||||
|
||||
def authenticate(self, request, code=None):
|
||||
def authenticate(self, request, code=None, state=None):
|
||||
log_prompt = "Process authenticate [OAuth2Backend]: {}"
|
||||
logger.debug(log_prompt.format('Start'))
|
||||
if code is None:
|
||||
logger.error(log_prompt.format('code is missing'))
|
||||
return None
|
||||
|
||||
if settings.AUTH_OAUTH2_USE_STATE:
|
||||
if state is None:
|
||||
logger.error(log_prompt.format('state is missing'))
|
||||
return None
|
||||
|
||||
session_state = request.session.get('oauth2_state')
|
||||
if not session_state or session_state != state:
|
||||
logger.error(log_prompt.format('state parameter mismatch'))
|
||||
return None
|
||||
|
||||
request.session.pop('oauth2_state', None)
|
||||
|
||||
query_dict = {
|
||||
'grant_type': 'authorization_code', 'code': code,
|
||||
'redirect_uri': build_absolute_uri(
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import uuid
|
||||
from django.conf import settings
|
||||
from django.contrib import auth
|
||||
from django.http import HttpResponseRedirect
|
||||
@@ -37,6 +38,11 @@ class OAuth2AuthRequestView(View):
|
||||
'redirect_uri': redirect_uri
|
||||
}
|
||||
|
||||
if settings.AUTH_OAUTH2_USE_STATE:
|
||||
state = uuid.uuid4()
|
||||
request.session['oauth2_state'] = state
|
||||
query_dict['state'] = state
|
||||
|
||||
if '?' in settings.AUTH_OAUTH2_PROVIDER_AUTHORIZATION_ENDPOINT:
|
||||
separator = '&'
|
||||
else:
|
||||
@@ -60,9 +66,19 @@ class OAuth2AuthCallbackView(View, FlashMessageMixin):
|
||||
logger.debug(log_prompt.format('Start'))
|
||||
callback_params = request.GET
|
||||
|
||||
state = None
|
||||
if settings.AUTH_OAUTH2_USE_STATE:
|
||||
state = callback_params.get('state')
|
||||
session_state = request.session.get('oauth2_state')
|
||||
if not state or not session_state or session_state != state:
|
||||
logger.error("Invalid state parameter")
|
||||
response = self.get_failed_response('/', title=_('OAuth2 Error'), msg="Invalid state parameter")
|
||||
return response
|
||||
request.session.pop('oauth2_state', None)
|
||||
|
||||
if 'code' in callback_params:
|
||||
logger.debug(log_prompt.format('Process authenticate'))
|
||||
user = authenticate(code=callback_params['code'], request=request)
|
||||
user = authenticate(code=callback_params['code'], request=request, state=state)
|
||||
|
||||
if user:
|
||||
logger.debug(log_prompt.format('Login: {}'.format(user)))
|
||||
|
||||
@@ -446,6 +446,7 @@ class Config(dict):
|
||||
'AUTH_OAUTH2': False,
|
||||
'AUTH_OAUTH2_LOGO_PATH': 'img/login_oauth2_logo.png',
|
||||
'AUTH_OAUTH2_PROVIDER': 'OAuth2',
|
||||
'AUTH_OAUTH2_USE_STATE': False,
|
||||
'AUTH_OAUTH2_ALWAYS_UPDATE_USER': True,
|
||||
'AUTH_OAUTH2_CLIENT_ID': 'client-id',
|
||||
'AUTH_OAUTH2_SCOPE': '',
|
||||
|
||||
@@ -203,6 +203,7 @@ SAML2_LOGOUT_URL_NAME = "authentication:saml2:saml2-logout"
|
||||
AUTH_OAUTH2 = CONFIG.AUTH_OAUTH2
|
||||
AUTH_OAUTH2_LOGO_PATH = CONFIG.AUTH_OAUTH2_LOGO_PATH
|
||||
AUTH_OAUTH2_PROVIDER = CONFIG.AUTH_OAUTH2_PROVIDER
|
||||
AUTH_OAUTH2_USE_STATE = CONFIG.AUTH_OAUTH2_USE_STATE
|
||||
AUTH_OAUTH2_ALWAYS_UPDATE_USER = CONFIG.AUTH_OAUTH2_ALWAYS_UPDATE_USER
|
||||
AUTH_OAUTH2_PROVIDER_AUTHORIZATION_ENDPOINT = CONFIG.AUTH_OAUTH2_PROVIDER_AUTHORIZATION_ENDPOINT
|
||||
AUTH_OAUTH2_ACCESS_TOKEN_ENDPOINT = CONFIG.AUTH_OAUTH2_ACCESS_TOKEN_ENDPOINT
|
||||
|
||||
Reference in New Issue
Block a user