providers/oauth2: remove response_type field as spec doesn't require validation
This commit is contained in:
parent
b04c9a2098
commit
ee2e737782
|
@ -20,7 +20,6 @@ class OAuth2ProviderSerializer(ModelSerializer, MetaNameSerializer):
|
||||||
"client_id",
|
"client_id",
|
||||||
"client_secret",
|
"client_secret",
|
||||||
"token_validity",
|
"token_validity",
|
||||||
"response_type",
|
|
||||||
"include_claims_in_id_token",
|
"include_claims_in_id_token",
|
||||||
"jwt_alg",
|
"jwt_alg",
|
||||||
"rsa_key",
|
"rsa_key",
|
||||||
|
|
|
@ -55,7 +55,6 @@ class OAuth2ProviderForm(forms.ModelForm):
|
||||||
"client_secret",
|
"client_secret",
|
||||||
"token_validity",
|
"token_validity",
|
||||||
"jwt_alg",
|
"jwt_alg",
|
||||||
"response_type",
|
|
||||||
"property_mappings",
|
"property_mappings",
|
||||||
"rsa_key",
|
"rsa_key",
|
||||||
"redirect_uris",
|
"redirect_uris",
|
||||||
|
|
|
@ -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",
|
||||||
|
),
|
||||||
|
]
|
|
@ -152,11 +152,6 @@ class OAuth2Provider(Provider):
|
||||||
verbose_name=_("Client Secret"),
|
verbose_name=_("Client Secret"),
|
||||||
default=generate_client_secret,
|
default=generate_client_secret,
|
||||||
)
|
)
|
||||||
response_type = models.TextField(
|
|
||||||
choices=ResponseTypes.choices,
|
|
||||||
default=ResponseTypes.CODE,
|
|
||||||
help_text=_(ResponseTypes.__doc__),
|
|
||||||
)
|
|
||||||
jwt_alg = models.CharField(
|
jwt_alg = models.CharField(
|
||||||
max_length=10,
|
max_length=10,
|
||||||
choices=JWTAlgorithms.choices,
|
choices=JWTAlgorithms.choices,
|
||||||
|
|
|
@ -106,7 +106,6 @@ class OAuthAuthorizationParams:
|
||||||
elif response_type in [
|
elif response_type in [
|
||||||
ResponseTypes.ID_TOKEN,
|
ResponseTypes.ID_TOKEN,
|
||||||
ResponseTypes.ID_TOKEN_TOKEN,
|
ResponseTypes.ID_TOKEN_TOKEN,
|
||||||
ResponseTypes.CODE_TOKEN,
|
|
||||||
]:
|
]:
|
||||||
grant_type = GrantTypes.IMPLICIT
|
grant_type = GrantTypes.IMPLICIT
|
||||||
elif response_type in [
|
elif response_type in [
|
||||||
|
@ -150,7 +149,6 @@ class OAuthAuthorizationParams:
|
||||||
self.check_redirect_uri()
|
self.check_redirect_uri()
|
||||||
self.check_scope()
|
self.check_scope()
|
||||||
self.check_nonce()
|
self.check_nonce()
|
||||||
self.check_response_type()
|
|
||||||
self.check_code_challenge()
|
self.check_code_challenge()
|
||||||
|
|
||||||
def check_redirect_uri(self):
|
def check_redirect_uri(self):
|
||||||
|
@ -203,18 +201,6 @@ class OAuthAuthorizationParams:
|
||||||
self.redirect_uri, "invalid_request", self.grant_type, self.state
|
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):
|
def check_code_challenge(self):
|
||||||
"""PKCE validation of the transformation method."""
|
"""PKCE validation of the transformation method."""
|
||||||
if self.code_challenge:
|
if self.code_challenge:
|
||||||
|
|
|
@ -13,7 +13,12 @@ from authentik.providers.oauth2.constants import (
|
||||||
GRANT_TYPE_REFRESH_TOKEN,
|
GRANT_TYPE_REFRESH_TOKEN,
|
||||||
SCOPE_OPENID,
|
SCOPE_OPENID,
|
||||||
)
|
)
|
||||||
from authentik.providers.oauth2.models import GrantTypes, OAuth2Provider, ScopeMapping
|
from authentik.providers.oauth2.models import (
|
||||||
|
GrantTypes,
|
||||||
|
OAuth2Provider,
|
||||||
|
ResponseTypes,
|
||||||
|
ScopeMapping,
|
||||||
|
)
|
||||||
|
|
||||||
LOGGER = get_logger()
|
LOGGER = get_logger()
|
||||||
|
|
||||||
|
@ -53,7 +58,14 @@ class ProviderInfoView(View):
|
||||||
"introspection_endpoint": self.request.build_absolute_uri(
|
"introspection_endpoint": self.request.build_absolute_uri(
|
||||||
reverse("authentik_providers_oauth2:token-introspection")
|
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(
|
"jwks_uri": self.request.build_absolute_uri(
|
||||||
reverse(
|
reverse(
|
||||||
"authentik_providers_oauth2:jwks",
|
"authentik_providers_oauth2:jwks",
|
||||||
|
|
|
@ -18,7 +18,6 @@ from authentik.providers.oauth2.models import (
|
||||||
AuthorizationCode,
|
AuthorizationCode,
|
||||||
OAuth2Provider,
|
OAuth2Provider,
|
||||||
RefreshToken,
|
RefreshToken,
|
||||||
ResponseTypes,
|
|
||||||
)
|
)
|
||||||
from authentik.providers.oauth2.utils import TokenResponse, extract_client_auth
|
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()),
|
"id_token": refresh_token.provider.encode(refresh_token.id_token.to_dict()),
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.params.provider.response_type == ResponseTypes.CODE_ADFS:
|
# if self.params.provider.response_type == ResponseTypes.CODE_ADFS:
|
||||||
# This seems to be expected by some OIDC Clients
|
# # This seems to be expected by some OIDC Clients
|
||||||
# namely VMware vCenter. This is not documented in any OpenID or OAuth2 Standard.
|
# # namely VMware vCenter. This is not documented in any OpenID or OAuth2 Standard.
|
||||||
# Maybe this should be a setting
|
# # Maybe this should be a setting
|
||||||
# in the future?
|
# # in the future?
|
||||||
response_dict["access_token"] = response_dict["id_token"]
|
# response_dict["access_token"] = response_dict["id_token"]
|
||||||
|
|
||||||
return response_dict
|
return response_dict
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,6 @@ from authentik.providers.oauth2.models import (
|
||||||
ClientTypes,
|
ClientTypes,
|
||||||
JWTAlgorithms,
|
JWTAlgorithms,
|
||||||
OAuth2Provider,
|
OAuth2Provider,
|
||||||
ResponseTypes,
|
|
||||||
ScopeMapping,
|
ScopeMapping,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -127,7 +126,6 @@ class ProxyProvider(OutpostModel, OAuth2Provider):
|
||||||
def set_oauth_defaults(self):
|
def set_oauth_defaults(self):
|
||||||
"""Ensure all OAuth2-related settings are correct"""
|
"""Ensure all OAuth2-related settings are correct"""
|
||||||
self.client_type = ClientTypes.CONFIDENTIAL
|
self.client_type = ClientTypes.CONFIDENTIAL
|
||||||
self.response_type = ResponseTypes.CODE
|
|
||||||
self.jwt_alg = JWTAlgorithms.RS256
|
self.jwt_alg = JWTAlgorithms.RS256
|
||||||
self.rsa_key = CertificateKeyPair.objects.first()
|
self.rsa_key = CertificateKeyPair.objects.first()
|
||||||
scopes = ScopeMapping.objects.filter(
|
scopes = ScopeMapping.objects.filter(
|
||||||
|
|
12
swagger.yaml
12
swagger.yaml
|
@ -7835,18 +7835,6 @@ definitions:
|
||||||
hours=1;minutes=2;seconds=3).'
|
hours=1;minutes=2;seconds=3).'
|
||||||
type: string
|
type: string
|
||||||
minLength: 1
|
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:
|
include_claims_in_id_token:
|
||||||
title: Include claims in id_token
|
title: Include claims in id_token
|
||||||
description: Include User claims from scopes in the id_token, for applications
|
description: Include User claims from scopes in the id_token, for applications
|
||||||
|
|
|
@ -17,7 +17,7 @@ from authentik.providers.oauth2.generators import (
|
||||||
generate_client_id,
|
generate_client_id,
|
||||||
generate_client_secret,
|
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
|
from tests.e2e.utils import USER, SeleniumTestCase, retry
|
||||||
|
|
||||||
|
|
||||||
|
@ -73,7 +73,6 @@ class TestProviderOAuth2Github(SeleniumTestCase):
|
||||||
client_id=self.client_id,
|
client_id=self.client_id,
|
||||||
client_secret=self.client_secret,
|
client_secret=self.client_secret,
|
||||||
client_type=ClientTypes.CONFIDENTIAL,
|
client_type=ClientTypes.CONFIDENTIAL,
|
||||||
response_type=ResponseTypes.CODE,
|
|
||||||
redirect_uris="http://localhost:3000/login/github",
|
redirect_uris="http://localhost:3000/login/github",
|
||||||
authorization_flow=authorization_flow,
|
authorization_flow=authorization_flow,
|
||||||
)
|
)
|
||||||
|
@ -128,7 +127,6 @@ class TestProviderOAuth2Github(SeleniumTestCase):
|
||||||
client_id=self.client_id,
|
client_id=self.client_id,
|
||||||
client_secret=self.client_secret,
|
client_secret=self.client_secret,
|
||||||
client_type=ClientTypes.CONFIDENTIAL,
|
client_type=ClientTypes.CONFIDENTIAL,
|
||||||
response_type=ResponseTypes.CODE,
|
|
||||||
redirect_uris="http://localhost:3000/login/github",
|
redirect_uris="http://localhost:3000/login/github",
|
||||||
authorization_flow=authorization_flow,
|
authorization_flow=authorization_flow,
|
||||||
)
|
)
|
||||||
|
@ -198,7 +196,6 @@ class TestProviderOAuth2Github(SeleniumTestCase):
|
||||||
client_id=self.client_id,
|
client_id=self.client_id,
|
||||||
client_secret=self.client_secret,
|
client_secret=self.client_secret,
|
||||||
client_type=ClientTypes.CONFIDENTIAL,
|
client_type=ClientTypes.CONFIDENTIAL,
|
||||||
response_type=ResponseTypes.CODE,
|
|
||||||
redirect_uris="http://localhost:3000/login/github",
|
redirect_uris="http://localhost:3000/login/github",
|
||||||
authorization_flow=authorization_flow,
|
authorization_flow=authorization_flow,
|
||||||
)
|
)
|
||||||
|
|
|
@ -24,12 +24,7 @@ from authentik.providers.oauth2.generators import (
|
||||||
generate_client_id,
|
generate_client_id,
|
||||||
generate_client_secret,
|
generate_client_secret,
|
||||||
)
|
)
|
||||||
from authentik.providers.oauth2.models import (
|
from authentik.providers.oauth2.models import ClientTypes, OAuth2Provider, ScopeMapping
|
||||||
ClientTypes,
|
|
||||||
OAuth2Provider,
|
|
||||||
ResponseTypes,
|
|
||||||
ScopeMapping,
|
|
||||||
)
|
|
||||||
from tests.e2e.utils import USER, SeleniumTestCase, retry
|
from tests.e2e.utils import USER, SeleniumTestCase, retry
|
||||||
|
|
||||||
LOGGER = get_logger()
|
LOGGER = get_logger()
|
||||||
|
@ -96,7 +91,6 @@ class TestProviderOAuth2OAuth(SeleniumTestCase):
|
||||||
rsa_key=CertificateKeyPair.objects.first(),
|
rsa_key=CertificateKeyPair.objects.first(),
|
||||||
redirect_uris="http://localhost:3000/",
|
redirect_uris="http://localhost:3000/",
|
||||||
authorization_flow=authorization_flow,
|
authorization_flow=authorization_flow,
|
||||||
response_type=ResponseTypes.CODE,
|
|
||||||
)
|
)
|
||||||
provider.property_mappings.set(
|
provider.property_mappings.set(
|
||||||
ScopeMapping.objects.filter(
|
ScopeMapping.objects.filter(
|
||||||
|
@ -134,7 +128,6 @@ class TestProviderOAuth2OAuth(SeleniumTestCase):
|
||||||
rsa_key=CertificateKeyPair.objects.first(),
|
rsa_key=CertificateKeyPair.objects.first(),
|
||||||
redirect_uris="http://localhost:3000/login/generic_oauth",
|
redirect_uris="http://localhost:3000/login/generic_oauth",
|
||||||
authorization_flow=authorization_flow,
|
authorization_flow=authorization_flow,
|
||||||
response_type=ResponseTypes.CODE,
|
|
||||||
)
|
)
|
||||||
provider.property_mappings.set(
|
provider.property_mappings.set(
|
||||||
ScopeMapping.objects.filter(
|
ScopeMapping.objects.filter(
|
||||||
|
@ -196,7 +189,6 @@ class TestProviderOAuth2OAuth(SeleniumTestCase):
|
||||||
rsa_key=CertificateKeyPair.objects.first(),
|
rsa_key=CertificateKeyPair.objects.first(),
|
||||||
redirect_uris="http://localhost:3000/login/generic_oauth",
|
redirect_uris="http://localhost:3000/login/generic_oauth",
|
||||||
authorization_flow=authorization_flow,
|
authorization_flow=authorization_flow,
|
||||||
response_type=ResponseTypes.CODE,
|
|
||||||
)
|
)
|
||||||
provider.property_mappings.set(
|
provider.property_mappings.set(
|
||||||
ScopeMapping.objects.filter(
|
ScopeMapping.objects.filter(
|
||||||
|
@ -261,7 +253,6 @@ class TestProviderOAuth2OAuth(SeleniumTestCase):
|
||||||
provider = OAuth2Provider.objects.create(
|
provider = OAuth2Provider.objects.create(
|
||||||
name="grafana",
|
name="grafana",
|
||||||
authorization_flow=authorization_flow,
|
authorization_flow=authorization_flow,
|
||||||
response_type=ResponseTypes.CODE,
|
|
||||||
client_type=ClientTypes.CONFIDENTIAL,
|
client_type=ClientTypes.CONFIDENTIAL,
|
||||||
client_id=self.client_id,
|
client_id=self.client_id,
|
||||||
client_secret=self.client_secret,
|
client_secret=self.client_secret,
|
||||||
|
@ -335,7 +326,6 @@ class TestProviderOAuth2OAuth(SeleniumTestCase):
|
||||||
provider = OAuth2Provider.objects.create(
|
provider = OAuth2Provider.objects.create(
|
||||||
name="grafana",
|
name="grafana",
|
||||||
authorization_flow=authorization_flow,
|
authorization_flow=authorization_flow,
|
||||||
response_type=ResponseTypes.CODE,
|
|
||||||
client_type=ClientTypes.CONFIDENTIAL,
|
client_type=ClientTypes.CONFIDENTIAL,
|
||||||
client_id=self.client_id,
|
client_id=self.client_id,
|
||||||
client_secret=self.client_secret,
|
client_secret=self.client_secret,
|
||||||
|
|
|
@ -26,12 +26,7 @@ from authentik.providers.oauth2.generators import (
|
||||||
generate_client_id,
|
generate_client_id,
|
||||||
generate_client_secret,
|
generate_client_secret,
|
||||||
)
|
)
|
||||||
from authentik.providers.oauth2.models import (
|
from authentik.providers.oauth2.models import ClientTypes, OAuth2Provider, ScopeMapping
|
||||||
ClientTypes,
|
|
||||||
OAuth2Provider,
|
|
||||||
ResponseTypes,
|
|
||||||
ScopeMapping,
|
|
||||||
)
|
|
||||||
from tests.e2e.utils import USER, SeleniumTestCase, retry
|
from tests.e2e.utils import USER, SeleniumTestCase, retry
|
||||||
|
|
||||||
LOGGER = get_logger()
|
LOGGER = get_logger()
|
||||||
|
@ -91,7 +86,6 @@ class TestProviderOAuth2OIDC(SeleniumTestCase):
|
||||||
rsa_key=CertificateKeyPair.objects.first(),
|
rsa_key=CertificateKeyPair.objects.first(),
|
||||||
redirect_uris="http://localhost:9009/",
|
redirect_uris="http://localhost:9009/",
|
||||||
authorization_flow=authorization_flow,
|
authorization_flow=authorization_flow,
|
||||||
response_type=ResponseTypes.CODE,
|
|
||||||
)
|
)
|
||||||
provider.property_mappings.set(
|
provider.property_mappings.set(
|
||||||
ScopeMapping.objects.filter(
|
ScopeMapping.objects.filter(
|
||||||
|
@ -129,7 +123,6 @@ class TestProviderOAuth2OIDC(SeleniumTestCase):
|
||||||
rsa_key=CertificateKeyPair.objects.first(),
|
rsa_key=CertificateKeyPair.objects.first(),
|
||||||
redirect_uris="http://localhost:9009/auth/callback",
|
redirect_uris="http://localhost:9009/auth/callback",
|
||||||
authorization_flow=authorization_flow,
|
authorization_flow=authorization_flow,
|
||||||
response_type=ResponseTypes.CODE,
|
|
||||||
)
|
)
|
||||||
provider.property_mappings.set(
|
provider.property_mappings.set(
|
||||||
ScopeMapping.objects.filter(
|
ScopeMapping.objects.filter(
|
||||||
|
@ -175,7 +168,6 @@ class TestProviderOAuth2OIDC(SeleniumTestCase):
|
||||||
provider = OAuth2Provider.objects.create(
|
provider = OAuth2Provider.objects.create(
|
||||||
name=self.application_slug,
|
name=self.application_slug,
|
||||||
authorization_flow=authorization_flow,
|
authorization_flow=authorization_flow,
|
||||||
response_type=ResponseTypes.CODE,
|
|
||||||
client_type=ClientTypes.CONFIDENTIAL,
|
client_type=ClientTypes.CONFIDENTIAL,
|
||||||
client_id=self.client_id,
|
client_id=self.client_id,
|
||||||
client_secret=self.client_secret,
|
client_secret=self.client_secret,
|
||||||
|
@ -236,7 +228,6 @@ class TestProviderOAuth2OIDC(SeleniumTestCase):
|
||||||
provider = OAuth2Provider.objects.create(
|
provider = OAuth2Provider.objects.create(
|
||||||
name=self.application_slug,
|
name=self.application_slug,
|
||||||
authorization_flow=authorization_flow,
|
authorization_flow=authorization_flow,
|
||||||
response_type=ResponseTypes.CODE,
|
|
||||||
client_type=ClientTypes.CONFIDENTIAL,
|
client_type=ClientTypes.CONFIDENTIAL,
|
||||||
client_id=self.client_id,
|
client_id=self.client_id,
|
||||||
client_secret=self.client_secret,
|
client_secret=self.client_secret,
|
||||||
|
|
|
@ -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:
|
Under _Providers_, create an OAuth2/OpenID Provider with these settings:
|
||||||
|
|
||||||
- Client Type: Confidential
|
- Client Type: Confidential
|
||||||
- Response Type: code (ADFS Compatibility Mode, sends id_token as access_token)
|
|
||||||
- JWT Algorithm: RS256
|
- JWT Algorithm: RS256
|
||||||
- Redirect URI: `https://vcenter.company/ui/login/oauth2/authcode`
|
- Redirect URI: `https://vcenter.company/ui/login/oauth2/authcode`
|
||||||
- Post Logout Redirect URIs: `https://vcenter.company/ui/login`
|
- Post Logout Redirect URIs: `https://vcenter.company/ui/login`
|
||||||
|
|
Reference in a new issue