Repository: goauthentik/authentik

Issue:
The Authorization Server requires End-User consent when set the offline_access scope
After updating to 2024.2.1, refresh_token required offline_access, When I set the provider scope and identified offline_access scope in the client. Authentik shown

consent_required: The Authorization Server requires End-User consent

Please, help me to solve this problem.



Discussion:
I had the same issue with my harbor instance after upgrading from 2023.10.7 -> 2024.2.1. For me it was solved when I placed the scopes in the same order as in authentik. I first added offline_access at the end, resulting in your issue. I have it now configured as this:
![image](https://github.com/goauthentik/authentik/assets/10989127/1e13ac40-0c52-453e-b190-71c46a7d888e)
![image](https://github.com/goauthentik/authentik/assets/10989127/0bac2f06-a552-4f4d-8f1f-1e45c4a22015)


I also have this issue with Grafana as the client (reordering the scopes did not help). The client needs to send a `prompt=consent` parameter when requesting `offline_access` scope ([#](https://openid.net/specs/openid-connect-core-1_0.html#OfflineAccess)), but Grafana doesn't do that.

If I manually add the `prompt` parameter to the auth URL in Grafana, it works and takes me to the consent page. E.g., `https://auth.example.com/application/o/authorize/?prompt=consent`

The error is coming from this line:

https://github.com/goauthentik/authentik/blob/73590572b0edd2d0754555c059a2f8cbab466a0b/authentik/providers/oauth2/views/authorize.py#L257-L260
Thank you @nima-karimi this worked. A downside is that the user always gets asked for their consent because the it is not saved in the user account anymore.

PS: If i set the Authorization Flow of the Provider from implicit to explicit the consent is saved. This seems kinda counterintuitive and in my opinion makes the use of the implicit flow useless. Is this the intended behaviour?
@nima-karimi I suppose there was a mistake in the interpretation of the spec there, seeing as if `prompt=consent` isn't set authentik is supposed to just pretend the `offline_access` scope wasn't requrested

@bbaumgartl The reason for this is when using a flow without a consent stage and the `prompt=consent` parameter is set, authentik will inject a consent stage into the flow that requires consent to always be given. If there already is such a stage in the flow (like with the default explicit authorization flow) then the OAuth provider can't change it so the settings of that stage will have higher priorty

Resolving patch:
diff --git a/authentik/providers/oauth2/views/authorize.py b/authentik/providers/oauth2/views/authorize.py
--- a/authentik/providers/oauth2/views/authorize.py
+++ b/authentik/providers/oauth2/views/authorize.py
@@ -255,9 +255,9 @@ def check_scope(self, github_compat=False):
         if SCOPE_OFFLINE_ACCESS in self.scope:
             # https://openid.net/specs/openid-connect-core-1_0.html#OfflineAccess
             if PROMPT_CONSENT not in self.prompt:
-                raise AuthorizeError(
-                    self.redirect_uri, "consent_required", self.grant_type, self.state
-                )
+                # Instead of ignoring the `offline_access` scope when `prompt`
+                # isn't set to `consent`, we set override it ourselves
+                self.prompt.add(PROMPT_CONSENT)
             if self.response_type not in [
                 ResponseTypes.CODE,
                 ResponseTypes.CODE_TOKEN,


Test patch: