providers/oauth2: Make AuthorizeError's state parameter requireed
This commit is contained in:
parent
e8debce9c8
commit
e7c96eb70d
|
@ -1,5 +1,4 @@
|
|||
"""OAuth errors"""
|
||||
from typing import Optional
|
||||
from urllib.parse import quote
|
||||
|
||||
from authentik.lib.sentry import SentryIgnoredException
|
||||
|
@ -105,7 +104,7 @@ class AuthorizeError(OAuth2Error):
|
|||
redirect_uri: str,
|
||||
error: str,
|
||||
grant_type: str,
|
||||
state: Optional[str] = None,
|
||||
state: str,
|
||||
):
|
||||
super().__init__()
|
||||
self.error = error
|
||||
|
@ -114,7 +113,7 @@ class AuthorizeError(OAuth2Error):
|
|||
self.grant_type = grant_type
|
||||
self.state = state
|
||||
|
||||
def create_uri(self, redirect_uri: str) -> str:
|
||||
def create_uri(self) -> str:
|
||||
"""Get a redirect URI with the error message"""
|
||||
description = quote(str(self.description))
|
||||
|
||||
|
@ -123,7 +122,7 @@ class AuthorizeError(OAuth2Error):
|
|||
hash_or_question = "#" if self.grant_type == GrantTypes.IMPLICIT else "?"
|
||||
|
||||
uri = "{0}{1}error={2}&error_description={3}".format(
|
||||
redirect_uri, hash_or_question, self.error, description
|
||||
self.redirect_uri, hash_or_question, self.error, description
|
||||
)
|
||||
|
||||
# Add state if present.
|
||||
|
|
|
@ -177,11 +177,15 @@ class OAuthAuthorizationParams:
|
|||
in [ResponseTypes.ID_TOKEN, ResponseTypes.ID_TOKEN_TOKEN]
|
||||
):
|
||||
LOGGER.warning("Missing 'openid' scope.")
|
||||
raise AuthorizeError(self.redirect_uri, "invalid_scope", self.grant_type)
|
||||
raise AuthorizeError(
|
||||
self.redirect_uri, "invalid_scope", self.grant_type, self.state
|
||||
)
|
||||
|
||||
# Nonce parameter validation.
|
||||
if is_open_id and self.grant_type == GrantTypes.IMPLICIT and not self.nonce:
|
||||
raise AuthorizeError(self.redirect_uri, "invalid_request", self.grant_type)
|
||||
raise AuthorizeError(
|
||||
self.redirect_uri, "invalid_request", self.grant_type, self.state
|
||||
)
|
||||
|
||||
# Response type parameter validation.
|
||||
if is_open_id:
|
||||
|
@ -191,14 +195,14 @@ class OAuthAuthorizationParams:
|
|||
actual_response_type = actual_response_type[:hash_index]
|
||||
if self.response_type != actual_response_type:
|
||||
raise AuthorizeError(
|
||||
self.redirect_uri, "invalid_request", self.grant_type
|
||||
self.redirect_uri, "invalid_request", self.grant_type, self.state
|
||||
)
|
||||
|
||||
# PKCE validation of the transformation method.
|
||||
if self.code_challenge:
|
||||
if not (self.code_challenge_method in ["plain", "S256"]):
|
||||
raise AuthorizeError(
|
||||
self.redirect_uri, "invalid_request", self.grant_type
|
||||
self.redirect_uri, "invalid_request", self.grant_type, self.state
|
||||
)
|
||||
|
||||
def create_code(self, request: HttpRequest) -> AuthorizationCode:
|
||||
|
@ -244,6 +248,7 @@ class OAuthFulfillmentStage(StageView):
|
|||
self.params.redirect_uri,
|
||||
"consent_required",
|
||||
self.params.grant_type,
|
||||
self.params.state,
|
||||
)
|
||||
Event.new(
|
||||
EventAction.AUTHORIZE_APPLICATION,
|
||||
|
@ -257,8 +262,7 @@ class OAuthFulfillmentStage(StageView):
|
|||
return bad_request_message(request, error.description, title=error.error)
|
||||
except AuthorizeError as error:
|
||||
self.executor.stage_invalid()
|
||||
uri = error.create_uri(self.params.redirect_uri)
|
||||
return redirect(uri)
|
||||
return redirect(error.create_uri())
|
||||
|
||||
def create_response_uri(self) -> str:
|
||||
"""Create a final Response URI the user is redirected to."""
|
||||
|
@ -361,7 +365,7 @@ class AuthorizationFlowInitView(PolicyAccessView):
|
|||
try:
|
||||
self.params = OAuthAuthorizationParams.from_request(self.request)
|
||||
except AuthorizeError as error:
|
||||
raise RequestValidationError(redirect(error.create_uri(error.redirect_uri)))
|
||||
raise RequestValidationError(redirect(error.create_uri()))
|
||||
except OAuth2Error as error:
|
||||
raise RequestValidationError(
|
||||
bad_request_message(self.request, error.description, title=error.error)
|
||||
|
@ -371,11 +375,12 @@ class AuthorizationFlowInitView(PolicyAccessView):
|
|||
if PROMPT_NONE in self.params.prompt and not self.request.user.is_authenticated:
|
||||
# When "prompt" is set to "none" but the user is not logged in, show an error message
|
||||
error = AuthorizeError(
|
||||
self.params.redirect_uri, "login_required", self.params.grant_type
|
||||
)
|
||||
raise RequestValidationError(
|
||||
redirect(error.create_uri(self.params.redirect_uri))
|
||||
self.params.redirect_uri,
|
||||
"login_required",
|
||||
self.params.grant_type,
|
||||
self.params.state,
|
||||
)
|
||||
raise RequestValidationError(redirect(error.create_uri()))
|
||||
|
||||
def resolve_provider_application(self):
|
||||
client_id = self.request.GET.get("client_id")
|
||||
|
|
Reference in a new issue