From 06df705240c3e74c5691b7ca5b4aa299fc8d967c Mon Sep 17 00:00:00 2001 From: Jens L Date: Fri, 22 Dec 2023 00:10:47 +0100 Subject: [PATCH] sources/oauth: fix missing get_user_id for OIDC-like sources (Azure AD) (#7970) * lib: add debug requests session that shows all sent requests Signed-off-by: Jens Langhammer * sources/oauth: fix missing get_user_id for OIDC-like OAuth Sources Signed-off-by: Jens Langhammer --------- Signed-off-by: Jens Langhammer --- authentik/lib/utils/http.py | 24 +++++++++++++++++++++-- authentik/sources/oauth/types/azure_ad.py | 6 +++--- authentik/sources/oauth/types/oidc.py | 2 +- authentik/sources/oauth/types/okta.py | 7 ++----- authentik/sources/oauth/types/twitch.py | 7 ++----- 5 files changed, 30 insertions(+), 16 deletions(-) diff --git a/authentik/lib/utils/http.py b/authentik/lib/utils/http.py index 3d6638104..f8d33db98 100644 --- a/authentik/lib/utils/http.py +++ b/authentik/lib/utils/http.py @@ -1,5 +1,8 @@ """http helpers""" -from requests.sessions import Session +from uuid import uuid4 + +from django.conf import settings +from requests.sessions import PreparedRequest, Session from structlog.stdlib import get_logger from authentik import get_full_version @@ -12,8 +15,25 @@ def authentik_user_agent() -> str: return f"authentik@{get_full_version()}" +class DebugSession(Session): + """requests session which logs http requests and responses""" + + def send(self, req: PreparedRequest, *args, **kwargs): + request_id = str(uuid4()) + LOGGER.debug("HTTP request sent", uid=request_id, path=req.path_url, headers=req.headers) + resp = super().send(req, *args, **kwargs) + LOGGER.debug( + "HTTP response received", + uid=request_id, + status=resp.status_code, + body=resp.text, + headers=resp.headers, + ) + return resp + + def get_http_session() -> Session: """Get a requests session with common headers""" - session = Session() + session = DebugSession() if settings.DEBUG else Session() session.headers["User-Agent"] = authentik_user_agent() return session diff --git a/authentik/sources/oauth/types/azure_ad.py b/authentik/sources/oauth/types/azure_ad.py index 39c744843..a247cea5d 100644 --- a/authentik/sources/oauth/types/azure_ad.py +++ b/authentik/sources/oauth/types/azure_ad.py @@ -4,8 +4,8 @@ from typing import Any from structlog.stdlib import get_logger from authentik.sources.oauth.clients.oauth2 import UserprofileHeaderAuthClient +from authentik.sources.oauth.types.oidc import OpenIDConnectOAuth2Callback from authentik.sources.oauth.types.registry import SourceType, registry -from authentik.sources.oauth.views.callback import OAuthCallback from authentik.sources.oauth.views.redirect import OAuthRedirect LOGGER = get_logger() @@ -20,7 +20,7 @@ class AzureADOAuthRedirect(OAuthRedirect): } -class AzureADOAuthCallback(OAuthCallback): +class AzureADOAuthCallback(OpenIDConnectOAuth2Callback): """AzureAD OAuth2 Callback""" client_class = UserprofileHeaderAuthClient @@ -50,7 +50,7 @@ class AzureADType(SourceType): authorization_url = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize" access_token_url = "https://login.microsoftonline.com/common/oauth2/v2.0/token" # nosec - profile_url = "https://graph.microsoft.com/v1.0/me" + profile_url = "https://login.microsoftonline.com/common/openid/userinfo" oidc_well_known_url = ( "https://login.microsoftonline.com/common/.well-known/openid-configuration" ) diff --git a/authentik/sources/oauth/types/oidc.py b/authentik/sources/oauth/types/oidc.py index 7ebd24579..bd6853117 100644 --- a/authentik/sources/oauth/types/oidc.py +++ b/authentik/sources/oauth/types/oidc.py @@ -23,7 +23,7 @@ class OpenIDConnectOAuth2Callback(OAuthCallback): client_class = UserprofileHeaderAuthClient def get_user_id(self, info: dict[str, str]) -> str: - return info.get("sub", "") + return info.get("sub", None) def get_user_enroll_context( self, diff --git a/authentik/sources/oauth/types/okta.py b/authentik/sources/oauth/types/okta.py index 8a305bce7..2de02edde 100644 --- a/authentik/sources/oauth/types/okta.py +++ b/authentik/sources/oauth/types/okta.py @@ -3,8 +3,8 @@ from typing import Any from authentik.sources.oauth.clients.oauth2 import UserprofileHeaderAuthClient from authentik.sources.oauth.models import OAuthSource +from authentik.sources.oauth.types.oidc import OpenIDConnectOAuth2Callback from authentik.sources.oauth.types.registry import SourceType, registry -from authentik.sources.oauth.views.callback import OAuthCallback from authentik.sources.oauth.views.redirect import OAuthRedirect @@ -17,7 +17,7 @@ class OktaOAuthRedirect(OAuthRedirect): } -class OktaOAuth2Callback(OAuthCallback): +class OktaOAuth2Callback(OpenIDConnectOAuth2Callback): """Okta OAuth2 Callback""" # Okta has the same quirk as azure and throws an error if the access token @@ -25,9 +25,6 @@ class OktaOAuth2Callback(OAuthCallback): # see https://github.com/goauthentik/authentik/issues/1910 client_class = UserprofileHeaderAuthClient - def get_user_id(self, info: dict[str, str]) -> str: - return info.get("sub", "") - def get_user_enroll_context( self, info: dict[str, Any], diff --git a/authentik/sources/oauth/types/twitch.py b/authentik/sources/oauth/types/twitch.py index 5fa9fad74..62e7b94d4 100644 --- a/authentik/sources/oauth/types/twitch.py +++ b/authentik/sources/oauth/types/twitch.py @@ -3,8 +3,8 @@ from json import dumps from typing import Any, Optional from authentik.sources.oauth.clients.oauth2 import UserprofileHeaderAuthClient +from authentik.sources.oauth.types.oidc import OpenIDConnectOAuth2Callback from authentik.sources.oauth.types.registry import SourceType, registry -from authentik.sources.oauth.views.callback import OAuthCallback from authentik.sources.oauth.views.redirect import OAuthRedirect @@ -27,14 +27,11 @@ class TwitchOAuthRedirect(OAuthRedirect): } -class TwitchOAuth2Callback(OAuthCallback): +class TwitchOAuth2Callback(OpenIDConnectOAuth2Callback): """Twitch OAuth2 Callback""" client_class = TwitchClient - def get_user_id(self, info: dict[str, str]) -> str: - return info.get("sub", "") - def get_user_enroll_context( self, info: dict[str, Any],