From ee2e73778295d037dae3ce42c9fc27348b49b4b3 Mon Sep 17 00:00:00 2001 From: Jens Langhammer Date: Sun, 27 Dec 2020 17:33:54 +0100 Subject: [PATCH] providers/oauth2: remove response_type field as spec doesn't require validation --- authentik/providers/oauth2/api.py | 1 - authentik/providers/oauth2/forms.py | 1 - .../0009_remove_oauth2provider_response_type.py | 17 +++++++++++++++++ authentik/providers/oauth2/models.py | 5 ----- authentik/providers/oauth2/views/authorize.py | 14 -------------- authentik/providers/oauth2/views/provider.py | 16 ++++++++++++++-- authentik/providers/oauth2/views/token.py | 13 ++++++------- authentik/providers/proxy/models.py | 2 -- swagger.yaml | 12 ------------ tests/e2e/test_provider_oauth2_github.py | 5 +---- tests/e2e/test_provider_oauth2_grafana.py | 12 +----------- tests/e2e/test_provider_oauth2_oidc.py | 11 +---------- .../services/vmware-vcenter/index.md | 1 - 13 files changed, 40 insertions(+), 70 deletions(-) create mode 100644 authentik/providers/oauth2/migrations/0009_remove_oauth2provider_response_type.py diff --git a/authentik/providers/oauth2/api.py b/authentik/providers/oauth2/api.py index 5b79ae37d..fc94493e6 100644 --- a/authentik/providers/oauth2/api.py +++ b/authentik/providers/oauth2/api.py @@ -20,7 +20,6 @@ class OAuth2ProviderSerializer(ModelSerializer, MetaNameSerializer): "client_id", "client_secret", "token_validity", - "response_type", "include_claims_in_id_token", "jwt_alg", "rsa_key", diff --git a/authentik/providers/oauth2/forms.py b/authentik/providers/oauth2/forms.py index f583a4473..92a1dd067 100644 --- a/authentik/providers/oauth2/forms.py +++ b/authentik/providers/oauth2/forms.py @@ -55,7 +55,6 @@ class OAuth2ProviderForm(forms.ModelForm): "client_secret", "token_validity", "jwt_alg", - "response_type", "property_mappings", "rsa_key", "redirect_uris", diff --git a/authentik/providers/oauth2/migrations/0009_remove_oauth2provider_response_type.py b/authentik/providers/oauth2/migrations/0009_remove_oauth2provider_response_type.py new file mode 100644 index 000000000..7dcf48ddb --- /dev/null +++ b/authentik/providers/oauth2/migrations/0009_remove_oauth2provider_response_type.py @@ -0,0 +1,17 @@ +# Generated by Django 3.1.4 on 2020-12-27 16:32 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("authentik_providers_oauth2", "0008_oauth2provider_issuer_mode"), + ] + + operations = [ + migrations.RemoveField( + model_name="oauth2provider", + name="response_type", + ), + ] diff --git a/authentik/providers/oauth2/models.py b/authentik/providers/oauth2/models.py index 1f9fa0d6a..99bda2c55 100644 --- a/authentik/providers/oauth2/models.py +++ b/authentik/providers/oauth2/models.py @@ -152,11 +152,6 @@ class OAuth2Provider(Provider): verbose_name=_("Client Secret"), default=generate_client_secret, ) - response_type = models.TextField( - choices=ResponseTypes.choices, - default=ResponseTypes.CODE, - help_text=_(ResponseTypes.__doc__), - ) jwt_alg = models.CharField( max_length=10, choices=JWTAlgorithms.choices, diff --git a/authentik/providers/oauth2/views/authorize.py b/authentik/providers/oauth2/views/authorize.py index 2cc05a2b7..c5392ace3 100644 --- a/authentik/providers/oauth2/views/authorize.py +++ b/authentik/providers/oauth2/views/authorize.py @@ -106,7 +106,6 @@ class OAuthAuthorizationParams: elif response_type in [ ResponseTypes.ID_TOKEN, ResponseTypes.ID_TOKEN_TOKEN, - ResponseTypes.CODE_TOKEN, ]: grant_type = GrantTypes.IMPLICIT elif response_type in [ @@ -150,7 +149,6 @@ class OAuthAuthorizationParams: self.check_redirect_uri() self.check_scope() self.check_nonce() - self.check_response_type() self.check_code_challenge() def check_redirect_uri(self): @@ -203,18 +201,6 @@ class OAuthAuthorizationParams: self.redirect_uri, "invalid_request", self.grant_type, self.state ) - def check_response_type(self): - """Response type parameter validation.""" - if SCOPE_OPENID in self.scope: - actual_response_type = self.provider.response_type - if "#" in self.provider.response_type: - hash_index = actual_response_type.index("#") - 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.state - ) - def check_code_challenge(self): """PKCE validation of the transformation method.""" if self.code_challenge: diff --git a/authentik/providers/oauth2/views/provider.py b/authentik/providers/oauth2/views/provider.py index f7d83cb8e..4caa90f8c 100644 --- a/authentik/providers/oauth2/views/provider.py +++ b/authentik/providers/oauth2/views/provider.py @@ -13,7 +13,12 @@ from authentik.providers.oauth2.constants import ( GRANT_TYPE_REFRESH_TOKEN, SCOPE_OPENID, ) -from authentik.providers.oauth2.models import GrantTypes, OAuth2Provider, ScopeMapping +from authentik.providers.oauth2.models import ( + GrantTypes, + OAuth2Provider, + ResponseTypes, + ScopeMapping, +) LOGGER = get_logger() @@ -53,7 +58,14 @@ class ProviderInfoView(View): "introspection_endpoint": self.request.build_absolute_uri( reverse("authentik_providers_oauth2:token-introspection") ), - "response_types_supported": [provider.response_type], + "response_types_supported": [ + ResponseTypes.CODE, + ResponseTypes.ID_TOKEN, + ResponseTypes.ID_TOKEN_TOKEN, + ResponseTypes.CODE_TOKEN, + ResponseTypes.CODE_ID_TOKEN, + ResponseTypes.CODE_ID_TOKEN_TOKEN, + ], "jwks_uri": self.request.build_absolute_uri( reverse( "authentik_providers_oauth2:jwks", diff --git a/authentik/providers/oauth2/views/token.py b/authentik/providers/oauth2/views/token.py index bb723865b..47a904210 100644 --- a/authentik/providers/oauth2/views/token.py +++ b/authentik/providers/oauth2/views/token.py @@ -18,7 +18,6 @@ from authentik.providers.oauth2.models import ( AuthorizationCode, OAuth2Provider, RefreshToken, - ResponseTypes, ) from authentik.providers.oauth2.utils import TokenResponse, extract_client_auth @@ -205,12 +204,12 @@ class TokenView(View): "id_token": refresh_token.provider.encode(refresh_token.id_token.to_dict()), } - if self.params.provider.response_type == ResponseTypes.CODE_ADFS: - # This seems to be expected by some OIDC Clients - # namely VMware vCenter. This is not documented in any OpenID or OAuth2 Standard. - # Maybe this should be a setting - # in the future? - response_dict["access_token"] = response_dict["id_token"] + # if self.params.provider.response_type == ResponseTypes.CODE_ADFS: + # # This seems to be expected by some OIDC Clients + # # namely VMware vCenter. This is not documented in any OpenID or OAuth2 Standard. + # # Maybe this should be a setting + # # in the future? + # response_dict["access_token"] = response_dict["id_token"] return response_dict diff --git a/authentik/providers/proxy/models.py b/authentik/providers/proxy/models.py index 92195dc4f..76392819d 100644 --- a/authentik/providers/proxy/models.py +++ b/authentik/providers/proxy/models.py @@ -22,7 +22,6 @@ from authentik.providers.oauth2.models import ( ClientTypes, JWTAlgorithms, OAuth2Provider, - ResponseTypes, ScopeMapping, ) @@ -127,7 +126,6 @@ class ProxyProvider(OutpostModel, OAuth2Provider): def set_oauth_defaults(self): """Ensure all OAuth2-related settings are correct""" self.client_type = ClientTypes.CONFIDENTIAL - self.response_type = ResponseTypes.CODE self.jwt_alg = JWTAlgorithms.RS256 self.rsa_key = CertificateKeyPair.objects.first() scopes = ScopeMapping.objects.filter( diff --git a/swagger.yaml b/swagger.yaml index 7fcdb62f5..6aca8b15b 100755 --- a/swagger.yaml +++ b/swagger.yaml @@ -7835,18 +7835,6 @@ definitions: hours=1;minutes=2;seconds=3).' type: string minLength: 1 - response_type: - title: Response type - description: Response Type required by the client. - type: string - enum: - - code - - code#adfs - - id_token - - id_token token - - code token - - code id_token - - code id_token token include_claims_in_id_token: title: Include claims in id_token description: Include User claims from scopes in the id_token, for applications diff --git a/tests/e2e/test_provider_oauth2_github.py b/tests/e2e/test_provider_oauth2_github.py index e2e5e03ba..8a21139b2 100644 --- a/tests/e2e/test_provider_oauth2_github.py +++ b/tests/e2e/test_provider_oauth2_github.py @@ -17,7 +17,7 @@ from authentik.providers.oauth2.generators import ( generate_client_id, generate_client_secret, ) -from authentik.providers.oauth2.models import ClientTypes, OAuth2Provider, ResponseTypes +from authentik.providers.oauth2.models import ClientTypes, OAuth2Provider from tests.e2e.utils import USER, SeleniumTestCase, retry @@ -73,7 +73,6 @@ class TestProviderOAuth2Github(SeleniumTestCase): client_id=self.client_id, client_secret=self.client_secret, client_type=ClientTypes.CONFIDENTIAL, - response_type=ResponseTypes.CODE, redirect_uris="http://localhost:3000/login/github", authorization_flow=authorization_flow, ) @@ -128,7 +127,6 @@ class TestProviderOAuth2Github(SeleniumTestCase): client_id=self.client_id, client_secret=self.client_secret, client_type=ClientTypes.CONFIDENTIAL, - response_type=ResponseTypes.CODE, redirect_uris="http://localhost:3000/login/github", authorization_flow=authorization_flow, ) @@ -198,7 +196,6 @@ class TestProviderOAuth2Github(SeleniumTestCase): client_id=self.client_id, client_secret=self.client_secret, client_type=ClientTypes.CONFIDENTIAL, - response_type=ResponseTypes.CODE, redirect_uris="http://localhost:3000/login/github", authorization_flow=authorization_flow, ) diff --git a/tests/e2e/test_provider_oauth2_grafana.py b/tests/e2e/test_provider_oauth2_grafana.py index b74d23dc1..9e20a3830 100644 --- a/tests/e2e/test_provider_oauth2_grafana.py +++ b/tests/e2e/test_provider_oauth2_grafana.py @@ -24,12 +24,7 @@ from authentik.providers.oauth2.generators import ( generate_client_id, generate_client_secret, ) -from authentik.providers.oauth2.models import ( - ClientTypes, - OAuth2Provider, - ResponseTypes, - ScopeMapping, -) +from authentik.providers.oauth2.models import ClientTypes, OAuth2Provider, ScopeMapping from tests.e2e.utils import USER, SeleniumTestCase, retry LOGGER = get_logger() @@ -96,7 +91,6 @@ class TestProviderOAuth2OAuth(SeleniumTestCase): rsa_key=CertificateKeyPair.objects.first(), redirect_uris="http://localhost:3000/", authorization_flow=authorization_flow, - response_type=ResponseTypes.CODE, ) provider.property_mappings.set( ScopeMapping.objects.filter( @@ -134,7 +128,6 @@ class TestProviderOAuth2OAuth(SeleniumTestCase): rsa_key=CertificateKeyPair.objects.first(), redirect_uris="http://localhost:3000/login/generic_oauth", authorization_flow=authorization_flow, - response_type=ResponseTypes.CODE, ) provider.property_mappings.set( ScopeMapping.objects.filter( @@ -196,7 +189,6 @@ class TestProviderOAuth2OAuth(SeleniumTestCase): rsa_key=CertificateKeyPair.objects.first(), redirect_uris="http://localhost:3000/login/generic_oauth", authorization_flow=authorization_flow, - response_type=ResponseTypes.CODE, ) provider.property_mappings.set( ScopeMapping.objects.filter( @@ -261,7 +253,6 @@ class TestProviderOAuth2OAuth(SeleniumTestCase): provider = OAuth2Provider.objects.create( name="grafana", authorization_flow=authorization_flow, - response_type=ResponseTypes.CODE, client_type=ClientTypes.CONFIDENTIAL, client_id=self.client_id, client_secret=self.client_secret, @@ -335,7 +326,6 @@ class TestProviderOAuth2OAuth(SeleniumTestCase): provider = OAuth2Provider.objects.create( name="grafana", authorization_flow=authorization_flow, - response_type=ResponseTypes.CODE, client_type=ClientTypes.CONFIDENTIAL, client_id=self.client_id, client_secret=self.client_secret, diff --git a/tests/e2e/test_provider_oauth2_oidc.py b/tests/e2e/test_provider_oauth2_oidc.py index c324a056d..438eaba99 100644 --- a/tests/e2e/test_provider_oauth2_oidc.py +++ b/tests/e2e/test_provider_oauth2_oidc.py @@ -26,12 +26,7 @@ from authentik.providers.oauth2.generators import ( generate_client_id, generate_client_secret, ) -from authentik.providers.oauth2.models import ( - ClientTypes, - OAuth2Provider, - ResponseTypes, - ScopeMapping, -) +from authentik.providers.oauth2.models import ClientTypes, OAuth2Provider, ScopeMapping from tests.e2e.utils import USER, SeleniumTestCase, retry LOGGER = get_logger() @@ -91,7 +86,6 @@ class TestProviderOAuth2OIDC(SeleniumTestCase): rsa_key=CertificateKeyPair.objects.first(), redirect_uris="http://localhost:9009/", authorization_flow=authorization_flow, - response_type=ResponseTypes.CODE, ) provider.property_mappings.set( ScopeMapping.objects.filter( @@ -129,7 +123,6 @@ class TestProviderOAuth2OIDC(SeleniumTestCase): rsa_key=CertificateKeyPair.objects.first(), redirect_uris="http://localhost:9009/auth/callback", authorization_flow=authorization_flow, - response_type=ResponseTypes.CODE, ) provider.property_mappings.set( ScopeMapping.objects.filter( @@ -175,7 +168,6 @@ class TestProviderOAuth2OIDC(SeleniumTestCase): provider = OAuth2Provider.objects.create( name=self.application_slug, authorization_flow=authorization_flow, - response_type=ResponseTypes.CODE, client_type=ClientTypes.CONFIDENTIAL, client_id=self.client_id, client_secret=self.client_secret, @@ -236,7 +228,6 @@ class TestProviderOAuth2OIDC(SeleniumTestCase): provider = OAuth2Provider.objects.create( name=self.application_slug, authorization_flow=authorization_flow, - response_type=ResponseTypes.CODE, client_type=ClientTypes.CONFIDENTIAL, client_id=self.client_id, client_secret=self.client_secret, diff --git a/website/docs/integrations/services/vmware-vcenter/index.md b/website/docs/integrations/services/vmware-vcenter/index.md index 4d7537c89..1af95c656 100644 --- a/website/docs/integrations/services/vmware-vcenter/index.md +++ b/website/docs/integrations/services/vmware-vcenter/index.md @@ -54,7 +54,6 @@ Under _Sources_, click _Edit_ and ensure that "Autogenerated Active Directory Ma Under _Providers_, create an OAuth2/OpenID Provider with these settings: - Client Type: Confidential -- Response Type: code (ADFS Compatibility Mode, sends id_token as access_token) - JWT Algorithm: RS256 - Redirect URI: `https://vcenter.company/ui/login/oauth2/authcode` - Post Logout Redirect URIs: `https://vcenter.company/ui/login`