authentik.providers.oauth2.views.token_revoke
Token revocation endpoint
1"""Token revocation endpoint""" 2 3from dataclasses import dataclass 4 5from django.http import Http404, HttpRequest, HttpResponse 6from django.utils.decorators import method_decorator 7from django.views import View 8from django.views.decorators.csrf import csrf_exempt 9from structlog.stdlib import get_logger 10 11from authentik.providers.oauth2.errors import TokenRevocationError 12from authentik.providers.oauth2.models import AccessToken, ClientTypes, OAuth2Provider, RefreshToken 13from authentik.providers.oauth2.utils import ( 14 TokenResponse, 15 authenticate_provider, 16 provider_from_request, 17) 18 19LOGGER = get_logger() 20 21 22@dataclass(slots=True) 23class TokenRevocationParams: 24 """Parameters for Token Revocation""" 25 26 token: RefreshToken | AccessToken 27 provider: OAuth2Provider 28 29 @staticmethod 30 def from_request(request: HttpRequest) -> TokenRevocationParams: 31 """Extract required Parameters from HTTP Request""" 32 raw_token = request.POST.get("token") 33 34 provider, _, _ = provider_from_request(request) 35 if provider and provider.client_type == ClientTypes.CONFIDENTIAL: 36 provider = authenticate_provider(request) 37 if not provider: 38 raise TokenRevocationError("invalid_client") 39 40 access_token = AccessToken.objects.filter(token=raw_token).first() 41 if access_token: 42 return TokenRevocationParams(access_token, provider) 43 refresh_token = RefreshToken.objects.filter(token=raw_token).first() 44 if refresh_token: 45 return TokenRevocationParams(refresh_token, provider) 46 LOGGER.debug("Token does not exist", token=raw_token) 47 raise Http404 48 49 50@method_decorator(csrf_exempt, name="dispatch") 51class TokenRevokeView(View): 52 """Token revoke endpoint 53 https://datatracker.ietf.org/doc/html/rfc7009""" 54 55 token: RefreshToken 56 params: TokenRevocationParams 57 provider: OAuth2Provider 58 59 def post(self, request: HttpRequest) -> HttpResponse: 60 """Revocation handler""" 61 try: 62 self.params = TokenRevocationParams.from_request(request) 63 64 self.params.token.delete() 65 66 return TokenResponse(data={}, status=200) 67 except TokenRevocationError as exc: 68 return TokenResponse(exc.create_dict(request), status=401) 69 except Http404: 70 # Token not found should return a HTTP 200 71 # https://datatracker.ietf.org/doc/html/rfc7009#section-2.2 72 return TokenResponse(data={}, status=200)
LOGGER =
<BoundLoggerLazyProxy(logger=None, wrapper_class=None, processors=None, context_class=None, initial_values={}, logger_factory_args=())>
@dataclass(slots=True)
class
TokenRevocationParams:
23@dataclass(slots=True) 24class TokenRevocationParams: 25 """Parameters for Token Revocation""" 26 27 token: RefreshToken | AccessToken 28 provider: OAuth2Provider 29 30 @staticmethod 31 def from_request(request: HttpRequest) -> TokenRevocationParams: 32 """Extract required Parameters from HTTP Request""" 33 raw_token = request.POST.get("token") 34 35 provider, _, _ = provider_from_request(request) 36 if provider and provider.client_type == ClientTypes.CONFIDENTIAL: 37 provider = authenticate_provider(request) 38 if not provider: 39 raise TokenRevocationError("invalid_client") 40 41 access_token = AccessToken.objects.filter(token=raw_token).first() 42 if access_token: 43 return TokenRevocationParams(access_token, provider) 44 refresh_token = RefreshToken.objects.filter(token=raw_token).first() 45 if refresh_token: 46 return TokenRevocationParams(refresh_token, provider) 47 LOGGER.debug("Token does not exist", token=raw_token) 48 raise Http404
Parameters for Token Revocation
TokenRevocationParams( token: authentik.providers.oauth2.models.RefreshToken | authentik.providers.oauth2.models.AccessToken, provider: authentik.providers.oauth2.models.OAuth2Provider)
token: authentik.providers.oauth2.models.RefreshToken | authentik.providers.oauth2.models.AccessToken
30 @staticmethod 31 def from_request(request: HttpRequest) -> TokenRevocationParams: 32 """Extract required Parameters from HTTP Request""" 33 raw_token = request.POST.get("token") 34 35 provider, _, _ = provider_from_request(request) 36 if provider and provider.client_type == ClientTypes.CONFIDENTIAL: 37 provider = authenticate_provider(request) 38 if not provider: 39 raise TokenRevocationError("invalid_client") 40 41 access_token = AccessToken.objects.filter(token=raw_token).first() 42 if access_token: 43 return TokenRevocationParams(access_token, provider) 44 refresh_token = RefreshToken.objects.filter(token=raw_token).first() 45 if refresh_token: 46 return TokenRevocationParams(refresh_token, provider) 47 LOGGER.debug("Token does not exist", token=raw_token) 48 raise Http404
Extract required Parameters from HTTP Request
@method_decorator(csrf_exempt, name='dispatch')
class
TokenRevokeView51@method_decorator(csrf_exempt, name="dispatch") 52class TokenRevokeView(View): 53 """Token revoke endpoint 54 https://datatracker.ietf.org/doc/html/rfc7009""" 55 56 token: RefreshToken 57 params: TokenRevocationParams 58 provider: OAuth2Provider 59 60 def post(self, request: HttpRequest) -> HttpResponse: 61 """Revocation handler""" 62 try: 63 self.params = TokenRevocationParams.from_request(request) 64 65 self.params.token.delete() 66 67 return TokenResponse(data={}, status=200) 68 except TokenRevocationError as exc: 69 return TokenResponse(exc.create_dict(request), status=401) 70 except Http404: 71 # Token not found should return a HTTP 200 72 # https://datatracker.ietf.org/doc/html/rfc7009#section-2.2 73 return TokenResponse(data={}, status=200)
Token revoke endpoint https://datatracker.ietf.org/doc/html/rfc7009
params: TokenRevocationParams
def
post( self, request: django.http.request.HttpRequest) -> django.http.response.HttpResponse:
60 def post(self, request: HttpRequest) -> HttpResponse: 61 """Revocation handler""" 62 try: 63 self.params = TokenRevocationParams.from_request(request) 64 65 self.params.token.delete() 66 67 return TokenResponse(data={}, status=200) 68 except TokenRevocationError as exc: 69 return TokenResponse(exc.create_dict(request), status=401) 70 except Http404: 71 # Token not found should return a HTTP 200 72 # https://datatracker.ietf.org/doc/html/rfc7009#section-2.2 73 return TokenResponse(data={}, status=200)
Revocation handler
def
dispatch(self, request, *args, **kwargs):
135 def dispatch(self, request, *args, **kwargs): 136 # Try to dispatch to the right method; if a method doesn't exist, 137 # defer to the error handler. Also defer to the error handler if the 138 # request method isn't on the approved list. 139 if request.method.lower() in self.http_method_names: 140 handler = getattr( 141 self, request.method.lower(), self.http_method_not_allowed 142 ) 143 else: 144 handler = self.http_method_not_allowed 145 return handler(request, *args, **kwargs)