diff --git a/authentik/providers/oauth2/urls.py b/authentik/providers/oauth2/urls.py index 1cbcb1a92..5c14f0cad 100644 --- a/authentik/providers/oauth2/urls.py +++ b/authentik/providers/oauth2/urls.py @@ -1,10 +1,7 @@ """OAuth provider URLs""" from django.urls import path -from django.views.decorators.csrf import csrf_exempt from django.views.generic.base import RedirectView -from authentik.providers.oauth2.constants import SCOPE_OPENID -from authentik.providers.oauth2.utils import protected_resource_view from authentik.providers.oauth2.views.authorize import AuthorizationFlowInitView from authentik.providers.oauth2.views.introspection import TokenIntrospectionView from authentik.providers.oauth2.views.jwks import JWKSView @@ -19,20 +16,20 @@ urlpatterns = [ AuthorizationFlowInitView.as_view(), name="authorize", ), - path("token/", csrf_exempt(TokenView.as_view()), name="token"), + path("token/", TokenView.as_view(), name="token"), path( "userinfo/", - csrf_exempt(protected_resource_view([SCOPE_OPENID])(UserInfoView.as_view())), + UserInfoView.as_view(), name="userinfo", ), path( "introspect/", - csrf_exempt(TokenIntrospectionView.as_view()), + TokenIntrospectionView.as_view(), name="token-introspection", ), path( "revoke/", - csrf_exempt(TokenRevokeView.as_view()), + TokenRevokeView.as_view(), name="token-revoke", ), path( diff --git a/authentik/providers/oauth2/urls_github.py b/authentik/providers/oauth2/urls_github.py index d33b66b66..c349cff5b 100644 --- a/authentik/providers/oauth2/urls_github.py +++ b/authentik/providers/oauth2/urls_github.py @@ -1,9 +1,6 @@ """authentik oauth_provider urls""" from django.urls import include, path -from django.views.decorators.csrf import csrf_exempt -from authentik.providers.oauth2.constants import SCOPE_GITHUB_ORG_READ, SCOPE_GITHUB_USER_EMAIL -from authentik.providers.oauth2.utils import protected_resource_view from authentik.providers.oauth2.views.authorize import AuthorizationFlowInitView from authentik.providers.oauth2.views.github import GitHubUserTeamsView, GitHubUserView from authentik.providers.oauth2.views.token import TokenView @@ -16,19 +13,17 @@ github_urlpatterns = [ ), path( "login/oauth/access_token", - csrf_exempt(TokenView.as_view()), + TokenView.as_view(), name="github-access-token", ), path( "user", - csrf_exempt(protected_resource_view([SCOPE_GITHUB_USER_EMAIL])(GitHubUserView.as_view())), + GitHubUserView.as_view(), name="github-user", ), path( "user/teams", - csrf_exempt( - protected_resource_view([SCOPE_GITHUB_ORG_READ])(GitHubUserTeamsView.as_view()) - ), + GitHubUserTeamsView.as_view(), name="github-user-teams", ), ] diff --git a/authentik/providers/oauth2/views/github.py b/authentik/providers/oauth2/views/github.py index a9fd0f93b..6c660a37c 100644 --- a/authentik/providers/oauth2/views/github.py +++ b/authentik/providers/oauth2/views/github.py @@ -1,12 +1,18 @@ """authentik pretend GitHub Views""" from django.http import HttpRequest, HttpResponse, JsonResponse +from django.utils.decorators import method_decorator from django.utils.text import slugify from django.views import View +from django.views.decorators.csrf import csrf_exempt +from authentik.providers.oauth2.constants import SCOPE_GITHUB_ORG_READ, SCOPE_GITHUB_USER_EMAIL from authentik.providers.oauth2.models import RefreshToken +from authentik.providers.oauth2.utils import protected_resource_view +@method_decorator(csrf_exempt, name="dispatch") +@method_decorator(protected_resource_view([SCOPE_GITHUB_USER_EMAIL]), name="dispatch") class GitHubUserView(View): """Emulate GitHub's /user API Endpoint""" @@ -62,6 +68,8 @@ class GitHubUserView(View): ) +@method_decorator(csrf_exempt, name="dispatch") +@method_decorator(protected_resource_view([SCOPE_GITHUB_ORG_READ]), name="dispatch") class GitHubUserTeamsView(View): """Emulate GitHub's /user/teams API Endpoint""" diff --git a/authentik/providers/oauth2/views/introspection.py b/authentik/providers/oauth2/views/introspection.py index a84fe8fc7..3a74d052d 100644 --- a/authentik/providers/oauth2/views/introspection.py +++ b/authentik/providers/oauth2/views/introspection.py @@ -2,7 +2,9 @@ from dataclasses import dataclass, field from django.http import HttpRequest, HttpResponse +from django.utils.decorators import method_decorator from django.views import View +from django.views.decorators.csrf import csrf_exempt from structlog.stdlib import get_logger from authentik.providers.oauth2.errors import TokenIntrospectionError @@ -59,6 +61,7 @@ class TokenIntrospectionParams: return TokenIntrospectionParams(token=token, provider=provider) +@method_decorator(csrf_exempt, name="dispatch") class TokenIntrospectionView(View): """Token Introspection https://tools.ietf.org/html/rfc7662""" diff --git a/authentik/providers/oauth2/views/token.py b/authentik/providers/oauth2/views/token.py index 1b2840a84..11a2aba42 100644 --- a/authentik/providers/oauth2/views/token.py +++ b/authentik/providers/oauth2/views/token.py @@ -7,8 +7,10 @@ from re import fullmatch from typing import Any, Optional from django.http import HttpRequest, HttpResponse +from django.utils.decorators import method_decorator from django.utils.timezone import datetime, now from django.views import View +from django.views.decorators.csrf import csrf_exempt from jwt import PyJWK, PyJWTError, decode from sentry_sdk.hub import Hub from structlog.stdlib import get_logger @@ -364,6 +366,7 @@ class TokenParams: self.user.save() +@method_decorator(csrf_exempt, name="dispatch") class TokenView(View): """Generate tokens for clients""" diff --git a/authentik/providers/oauth2/views/token_revoke.py b/authentik/providers/oauth2/views/token_revoke.py index 6b83caeae..d7584a5ac 100644 --- a/authentik/providers/oauth2/views/token_revoke.py +++ b/authentik/providers/oauth2/views/token_revoke.py @@ -2,7 +2,9 @@ from dataclasses import dataclass from django.http import Http404, HttpRequest, HttpResponse +from django.utils.decorators import method_decorator from django.views import View +from django.views.decorators.csrf import csrf_exempt from structlog.stdlib import get_logger from authentik.providers.oauth2.errors import TokenRevocationError @@ -43,6 +45,7 @@ class TokenRevocationParams: return TokenRevocationParams(token=token, provider=provider) +@method_decorator(csrf_exempt, name="dispatch") class TokenRevokeView(View): """Token revoke endpoint https://datatracker.ietf.org/doc/html/rfc7009""" diff --git a/authentik/providers/oauth2/views/userinfo.py b/authentik/providers/oauth2/views/userinfo.py index 4a6f0de9c..eef88cf71 100644 --- a/authentik/providers/oauth2/views/userinfo.py +++ b/authentik/providers/oauth2/views/userinfo.py @@ -4,8 +4,10 @@ from typing import Any, Optional from deepmerge import always_merger from django.http import HttpRequest, HttpResponse from django.http.response import HttpResponseBadRequest +from django.utils.decorators import method_decorator from django.utils.translation import gettext_lazy as _ from django.views import View +from django.views.decorators.csrf import csrf_exempt from structlog.stdlib import get_logger from authentik.core.exceptions import PropertyMappingExpressionException @@ -17,13 +19,16 @@ from authentik.providers.oauth2.constants import ( SCOPE_GITHUB_USER, SCOPE_GITHUB_USER_EMAIL, SCOPE_GITHUB_USER_READ, + SCOPE_OPENID, ) from authentik.providers.oauth2.models import RefreshToken, ScopeMapping -from authentik.providers.oauth2.utils import TokenResponse, cors_allow +from authentik.providers.oauth2.utils import TokenResponse, cors_allow, protected_resource_view LOGGER = get_logger() +@method_decorator(csrf_exempt, name="dispatch") +@method_decorator(protected_resource_view([SCOPE_OPENID]), name="dispatch") class UserInfoView(View): """Create a dictionary with all the requested claims about the End-User. See: http://openid.net/specs/openid-connect-core-1_0.html#UserInfoResponse"""