authentik.providers.oauth2.tests.test_token_cc_standard
Test token view
1"""Test token view""" 2 3from json import loads 4 5from django.test import RequestFactory 6from django.urls import reverse 7from jwt import decode 8 9from authentik.blueprints.tests import apply_blueprint 10from authentik.common.oauth.constants import ( 11 GRANT_TYPE_CLIENT_CREDENTIALS, 12 GRANT_TYPE_PASSWORD, 13 SCOPE_OPENID, 14 SCOPE_OPENID_EMAIL, 15 SCOPE_OPENID_PROFILE, 16 TOKEN_TYPE, 17) 18from authentik.core.models import Application, Group, Token, TokenIntents, UserTypes 19from authentik.core.tests.utils import create_test_admin_user, create_test_cert, create_test_flow 20from authentik.policies.models import PolicyBinding 21from authentik.providers.oauth2.errors import TokenError 22from authentik.providers.oauth2.models import ( 23 AccessToken, 24 GrantType, 25 OAuth2Provider, 26 RedirectURI, 27 RedirectURIMatchingMode, 28 ScopeMapping, 29) 30from authentik.providers.oauth2.tests.utils import OAuthTestCase 31 32 33class TestTokenClientCredentialsStandard(OAuthTestCase): 34 """Test token (client_credentials) view""" 35 36 @apply_blueprint("system/providers-oauth2.yaml") 37 def setUp(self) -> None: 38 super().setUp() 39 self.factory = RequestFactory() 40 self.provider = OAuth2Provider.objects.create( 41 name="test", 42 authorization_flow=create_test_flow(), 43 redirect_uris=[RedirectURI(RedirectURIMatchingMode.STRICT, "http://testserver")], 44 signing_key=create_test_cert(), 45 grant_types=[GrantType.CLIENT_CREDENTIALS, GrantType.PASSWORD], 46 ) 47 self.provider.property_mappings.set(ScopeMapping.objects.all()) 48 self.app = Application.objects.create(name="test", slug="test", provider=self.provider) 49 self.user = create_test_admin_user("sa") 50 self.user.type = UserTypes.SERVICE_ACCOUNT 51 self.user.save() 52 self.token = Token.objects.create( 53 identifier="sa-token", 54 user=self.user, 55 intent=TokenIntents.INTENT_APP_PASSWORD, 56 expiring=False, 57 ) 58 59 def test_wrong_user(self): 60 """test invalid username""" 61 response = self.client.post( 62 reverse("authentik_providers_oauth2:token"), 63 { 64 "grant_type": GRANT_TYPE_CLIENT_CREDENTIALS, 65 "scope": SCOPE_OPENID, 66 "client_id": self.provider.client_id, 67 "client_secret": self.provider.client_secret + "foo", 68 }, 69 ) 70 self.assertEqual(response.status_code, 400) 71 self.assertJSONEqual( 72 response.content.decode(), 73 { 74 "error": "invalid_grant", 75 "error_description": TokenError.errors["invalid_grant"], 76 "request_id": response.headers["X-authentik-id"], 77 }, 78 ) 79 80 def test_no_provider(self): 81 """test no provider""" 82 self.app.provider = None 83 self.app.save() 84 response = self.client.post( 85 reverse("authentik_providers_oauth2:token"), 86 { 87 "grant_type": GRANT_TYPE_CLIENT_CREDENTIALS, 88 "scope": SCOPE_OPENID, 89 "client_id": self.provider.client_id, 90 "client_secret": self.provider.client_secret, 91 }, 92 ) 93 self.assertEqual(response.status_code, 400) 94 self.assertJSONEqual( 95 response.content.decode(), 96 { 97 "error": "invalid_grant", 98 "error_description": TokenError.errors["invalid_grant"], 99 "request_id": response.headers["X-authentik-id"], 100 }, 101 ) 102 103 def test_permission_denied(self): 104 """test permission denied""" 105 group = Group.objects.create(name="foo") 106 PolicyBinding.objects.create( 107 group=group, 108 target=self.app, 109 order=0, 110 ) 111 response = self.client.post( 112 reverse("authentik_providers_oauth2:token"), 113 { 114 "grant_type": GRANT_TYPE_CLIENT_CREDENTIALS, 115 "scope": SCOPE_OPENID, 116 "client_id": self.provider.client_id, 117 "client_secret": self.provider.client_secret, 118 }, 119 ) 120 self.assertEqual(response.status_code, 400) 121 self.assertJSONEqual( 122 response.content.decode(), 123 { 124 "error": "invalid_grant", 125 "error_description": TokenError.errors["invalid_grant"], 126 "request_id": response.headers["X-authentik-id"], 127 }, 128 ) 129 130 def test_incorrect_scopes(self): 131 """test scope that isn't configured""" 132 response = self.client.post( 133 reverse("authentik_providers_oauth2:token"), 134 { 135 "grant_type": GRANT_TYPE_CLIENT_CREDENTIALS, 136 "scope": f"{SCOPE_OPENID} {SCOPE_OPENID_EMAIL} {SCOPE_OPENID_PROFILE} extra_scope", 137 "client_id": self.provider.client_id, 138 "client_secret": self.provider.client_secret, 139 }, 140 ) 141 self.assertEqual(response.status_code, 200) 142 body = loads(response.content.decode()) 143 self.assertEqual(body["token_type"], TOKEN_TYPE) 144 token = AccessToken.objects.filter( 145 provider=self.provider, token=body["access_token"] 146 ).first() 147 self.assertSetEqual( 148 set(token.scope), {SCOPE_OPENID, SCOPE_OPENID_EMAIL, SCOPE_OPENID_PROFILE} 149 ) 150 _, alg = self.provider.jwt_key 151 jwt = decode( 152 body["access_token"], 153 key=self.provider.signing_key.public_key, 154 algorithms=[alg], 155 audience=self.provider.client_id, 156 ) 157 self.assertEqual( 158 jwt["given_name"], "Autogenerated user from application test (client credentials)" 159 ) 160 self.assertEqual(jwt["preferred_username"], "ak-test-client_credentials") 161 jwt = decode( 162 body["id_token"], 163 key=self.provider.signing_key.public_key, 164 algorithms=[alg], 165 audience=self.provider.client_id, 166 ) 167 self.assertEqual( 168 jwt["given_name"], "Autogenerated user from application test (client credentials)" 169 ) 170 self.assertEqual(jwt["preferred_username"], "ak-test-client_credentials") 171 172 def test_successful(self): 173 """test successful""" 174 response = self.client.post( 175 reverse("authentik_providers_oauth2:token"), 176 { 177 "grant_type": GRANT_TYPE_CLIENT_CREDENTIALS, 178 "scope": f"{SCOPE_OPENID} {SCOPE_OPENID_EMAIL} {SCOPE_OPENID_PROFILE}", 179 "client_id": self.provider.client_id, 180 "client_secret": self.provider.client_secret, 181 }, 182 ) 183 self.assertEqual(response.status_code, 200) 184 body = loads(response.content.decode()) 185 self.assertEqual(body["token_type"], TOKEN_TYPE) 186 _, alg = self.provider.jwt_key 187 jwt = decode( 188 body["access_token"], 189 key=self.provider.signing_key.public_key, 190 algorithms=[alg], 191 audience=self.provider.client_id, 192 ) 193 self.assertEqual( 194 jwt["given_name"], "Autogenerated user from application test (client credentials)" 195 ) 196 self.assertEqual(jwt["preferred_username"], "ak-test-client_credentials") 197 jwt = decode( 198 body["id_token"], 199 key=self.provider.signing_key.public_key, 200 algorithms=[alg], 201 audience=self.provider.client_id, 202 ) 203 self.assertEqual( 204 jwt["given_name"], "Autogenerated user from application test (client credentials)" 205 ) 206 self.assertEqual(jwt["preferred_username"], "ak-test-client_credentials") 207 208 def test_successful_password(self): 209 """test successful (password grant)""" 210 response = self.client.post( 211 reverse("authentik_providers_oauth2:token"), 212 { 213 "grant_type": GRANT_TYPE_PASSWORD, 214 "scope": f"{SCOPE_OPENID} {SCOPE_OPENID_EMAIL} {SCOPE_OPENID_PROFILE}", 215 "client_id": self.provider.client_id, 216 "client_secret": self.provider.client_secret, 217 }, 218 ) 219 self.assertEqual(response.status_code, 200) 220 body = loads(response.content.decode()) 221 self.assertEqual(body["token_type"], TOKEN_TYPE) 222 _, alg = self.provider.jwt_key 223 jwt = decode( 224 body["access_token"], 225 key=self.provider.signing_key.public_key, 226 algorithms=[alg], 227 audience=self.provider.client_id, 228 ) 229 self.assertEqual( 230 jwt["given_name"], "Autogenerated user from application test (client credentials)" 231 ) 232 self.assertEqual(jwt["preferred_username"], "ak-test-client_credentials")
34class TestTokenClientCredentialsStandard(OAuthTestCase): 35 """Test token (client_credentials) view""" 36 37 @apply_blueprint("system/providers-oauth2.yaml") 38 def setUp(self) -> None: 39 super().setUp() 40 self.factory = RequestFactory() 41 self.provider = OAuth2Provider.objects.create( 42 name="test", 43 authorization_flow=create_test_flow(), 44 redirect_uris=[RedirectURI(RedirectURIMatchingMode.STRICT, "http://testserver")], 45 signing_key=create_test_cert(), 46 grant_types=[GrantType.CLIENT_CREDENTIALS, GrantType.PASSWORD], 47 ) 48 self.provider.property_mappings.set(ScopeMapping.objects.all()) 49 self.app = Application.objects.create(name="test", slug="test", provider=self.provider) 50 self.user = create_test_admin_user("sa") 51 self.user.type = UserTypes.SERVICE_ACCOUNT 52 self.user.save() 53 self.token = Token.objects.create( 54 identifier="sa-token", 55 user=self.user, 56 intent=TokenIntents.INTENT_APP_PASSWORD, 57 expiring=False, 58 ) 59 60 def test_wrong_user(self): 61 """test invalid username""" 62 response = self.client.post( 63 reverse("authentik_providers_oauth2:token"), 64 { 65 "grant_type": GRANT_TYPE_CLIENT_CREDENTIALS, 66 "scope": SCOPE_OPENID, 67 "client_id": self.provider.client_id, 68 "client_secret": self.provider.client_secret + "foo", 69 }, 70 ) 71 self.assertEqual(response.status_code, 400) 72 self.assertJSONEqual( 73 response.content.decode(), 74 { 75 "error": "invalid_grant", 76 "error_description": TokenError.errors["invalid_grant"], 77 "request_id": response.headers["X-authentik-id"], 78 }, 79 ) 80 81 def test_no_provider(self): 82 """test no provider""" 83 self.app.provider = None 84 self.app.save() 85 response = self.client.post( 86 reverse("authentik_providers_oauth2:token"), 87 { 88 "grant_type": GRANT_TYPE_CLIENT_CREDENTIALS, 89 "scope": SCOPE_OPENID, 90 "client_id": self.provider.client_id, 91 "client_secret": self.provider.client_secret, 92 }, 93 ) 94 self.assertEqual(response.status_code, 400) 95 self.assertJSONEqual( 96 response.content.decode(), 97 { 98 "error": "invalid_grant", 99 "error_description": TokenError.errors["invalid_grant"], 100 "request_id": response.headers["X-authentik-id"], 101 }, 102 ) 103 104 def test_permission_denied(self): 105 """test permission denied""" 106 group = Group.objects.create(name="foo") 107 PolicyBinding.objects.create( 108 group=group, 109 target=self.app, 110 order=0, 111 ) 112 response = self.client.post( 113 reverse("authentik_providers_oauth2:token"), 114 { 115 "grant_type": GRANT_TYPE_CLIENT_CREDENTIALS, 116 "scope": SCOPE_OPENID, 117 "client_id": self.provider.client_id, 118 "client_secret": self.provider.client_secret, 119 }, 120 ) 121 self.assertEqual(response.status_code, 400) 122 self.assertJSONEqual( 123 response.content.decode(), 124 { 125 "error": "invalid_grant", 126 "error_description": TokenError.errors["invalid_grant"], 127 "request_id": response.headers["X-authentik-id"], 128 }, 129 ) 130 131 def test_incorrect_scopes(self): 132 """test scope that isn't configured""" 133 response = self.client.post( 134 reverse("authentik_providers_oauth2:token"), 135 { 136 "grant_type": GRANT_TYPE_CLIENT_CREDENTIALS, 137 "scope": f"{SCOPE_OPENID} {SCOPE_OPENID_EMAIL} {SCOPE_OPENID_PROFILE} extra_scope", 138 "client_id": self.provider.client_id, 139 "client_secret": self.provider.client_secret, 140 }, 141 ) 142 self.assertEqual(response.status_code, 200) 143 body = loads(response.content.decode()) 144 self.assertEqual(body["token_type"], TOKEN_TYPE) 145 token = AccessToken.objects.filter( 146 provider=self.provider, token=body["access_token"] 147 ).first() 148 self.assertSetEqual( 149 set(token.scope), {SCOPE_OPENID, SCOPE_OPENID_EMAIL, SCOPE_OPENID_PROFILE} 150 ) 151 _, alg = self.provider.jwt_key 152 jwt = decode( 153 body["access_token"], 154 key=self.provider.signing_key.public_key, 155 algorithms=[alg], 156 audience=self.provider.client_id, 157 ) 158 self.assertEqual( 159 jwt["given_name"], "Autogenerated user from application test (client credentials)" 160 ) 161 self.assertEqual(jwt["preferred_username"], "ak-test-client_credentials") 162 jwt = decode( 163 body["id_token"], 164 key=self.provider.signing_key.public_key, 165 algorithms=[alg], 166 audience=self.provider.client_id, 167 ) 168 self.assertEqual( 169 jwt["given_name"], "Autogenerated user from application test (client credentials)" 170 ) 171 self.assertEqual(jwt["preferred_username"], "ak-test-client_credentials") 172 173 def test_successful(self): 174 """test successful""" 175 response = self.client.post( 176 reverse("authentik_providers_oauth2:token"), 177 { 178 "grant_type": GRANT_TYPE_CLIENT_CREDENTIALS, 179 "scope": f"{SCOPE_OPENID} {SCOPE_OPENID_EMAIL} {SCOPE_OPENID_PROFILE}", 180 "client_id": self.provider.client_id, 181 "client_secret": self.provider.client_secret, 182 }, 183 ) 184 self.assertEqual(response.status_code, 200) 185 body = loads(response.content.decode()) 186 self.assertEqual(body["token_type"], TOKEN_TYPE) 187 _, alg = self.provider.jwt_key 188 jwt = decode( 189 body["access_token"], 190 key=self.provider.signing_key.public_key, 191 algorithms=[alg], 192 audience=self.provider.client_id, 193 ) 194 self.assertEqual( 195 jwt["given_name"], "Autogenerated user from application test (client credentials)" 196 ) 197 self.assertEqual(jwt["preferred_username"], "ak-test-client_credentials") 198 jwt = decode( 199 body["id_token"], 200 key=self.provider.signing_key.public_key, 201 algorithms=[alg], 202 audience=self.provider.client_id, 203 ) 204 self.assertEqual( 205 jwt["given_name"], "Autogenerated user from application test (client credentials)" 206 ) 207 self.assertEqual(jwt["preferred_username"], "ak-test-client_credentials") 208 209 def test_successful_password(self): 210 """test successful (password grant)""" 211 response = self.client.post( 212 reverse("authentik_providers_oauth2:token"), 213 { 214 "grant_type": GRANT_TYPE_PASSWORD, 215 "scope": f"{SCOPE_OPENID} {SCOPE_OPENID_EMAIL} {SCOPE_OPENID_PROFILE}", 216 "client_id": self.provider.client_id, 217 "client_secret": self.provider.client_secret, 218 }, 219 ) 220 self.assertEqual(response.status_code, 200) 221 body = loads(response.content.decode()) 222 self.assertEqual(body["token_type"], TOKEN_TYPE) 223 _, alg = self.provider.jwt_key 224 jwt = decode( 225 body["access_token"], 226 key=self.provider.signing_key.public_key, 227 algorithms=[alg], 228 audience=self.provider.client_id, 229 ) 230 self.assertEqual( 231 jwt["given_name"], "Autogenerated user from application test (client credentials)" 232 ) 233 self.assertEqual(jwt["preferred_username"], "ak-test-client_credentials")
Test token (client_credentials) view
@apply_blueprint('system/providers-oauth2.yaml')
def
setUp(self) -> None:
37 @apply_blueprint("system/providers-oauth2.yaml") 38 def setUp(self) -> None: 39 super().setUp() 40 self.factory = RequestFactory() 41 self.provider = OAuth2Provider.objects.create( 42 name="test", 43 authorization_flow=create_test_flow(), 44 redirect_uris=[RedirectURI(RedirectURIMatchingMode.STRICT, "http://testserver")], 45 signing_key=create_test_cert(), 46 grant_types=[GrantType.CLIENT_CREDENTIALS, GrantType.PASSWORD], 47 ) 48 self.provider.property_mappings.set(ScopeMapping.objects.all()) 49 self.app = Application.objects.create(name="test", slug="test", provider=self.provider) 50 self.user = create_test_admin_user("sa") 51 self.user.type = UserTypes.SERVICE_ACCOUNT 52 self.user.save() 53 self.token = Token.objects.create( 54 identifier="sa-token", 55 user=self.user, 56 intent=TokenIntents.INTENT_APP_PASSWORD, 57 expiring=False, 58 )
Hook method for setting up the test fixture before exercising it.
def
test_wrong_user(self):
60 def test_wrong_user(self): 61 """test invalid username""" 62 response = self.client.post( 63 reverse("authentik_providers_oauth2:token"), 64 { 65 "grant_type": GRANT_TYPE_CLIENT_CREDENTIALS, 66 "scope": SCOPE_OPENID, 67 "client_id": self.provider.client_id, 68 "client_secret": self.provider.client_secret + "foo", 69 }, 70 ) 71 self.assertEqual(response.status_code, 400) 72 self.assertJSONEqual( 73 response.content.decode(), 74 { 75 "error": "invalid_grant", 76 "error_description": TokenError.errors["invalid_grant"], 77 "request_id": response.headers["X-authentik-id"], 78 }, 79 )
test invalid username
def
test_no_provider(self):
81 def test_no_provider(self): 82 """test no provider""" 83 self.app.provider = None 84 self.app.save() 85 response = self.client.post( 86 reverse("authentik_providers_oauth2:token"), 87 { 88 "grant_type": GRANT_TYPE_CLIENT_CREDENTIALS, 89 "scope": SCOPE_OPENID, 90 "client_id": self.provider.client_id, 91 "client_secret": self.provider.client_secret, 92 }, 93 ) 94 self.assertEqual(response.status_code, 400) 95 self.assertJSONEqual( 96 response.content.decode(), 97 { 98 "error": "invalid_grant", 99 "error_description": TokenError.errors["invalid_grant"], 100 "request_id": response.headers["X-authentik-id"], 101 }, 102 )
test no provider
def
test_permission_denied(self):
104 def test_permission_denied(self): 105 """test permission denied""" 106 group = Group.objects.create(name="foo") 107 PolicyBinding.objects.create( 108 group=group, 109 target=self.app, 110 order=0, 111 ) 112 response = self.client.post( 113 reverse("authentik_providers_oauth2:token"), 114 { 115 "grant_type": GRANT_TYPE_CLIENT_CREDENTIALS, 116 "scope": SCOPE_OPENID, 117 "client_id": self.provider.client_id, 118 "client_secret": self.provider.client_secret, 119 }, 120 ) 121 self.assertEqual(response.status_code, 400) 122 self.assertJSONEqual( 123 response.content.decode(), 124 { 125 "error": "invalid_grant", 126 "error_description": TokenError.errors["invalid_grant"], 127 "request_id": response.headers["X-authentik-id"], 128 }, 129 )
test permission denied
def
test_incorrect_scopes(self):
131 def test_incorrect_scopes(self): 132 """test scope that isn't configured""" 133 response = self.client.post( 134 reverse("authentik_providers_oauth2:token"), 135 { 136 "grant_type": GRANT_TYPE_CLIENT_CREDENTIALS, 137 "scope": f"{SCOPE_OPENID} {SCOPE_OPENID_EMAIL} {SCOPE_OPENID_PROFILE} extra_scope", 138 "client_id": self.provider.client_id, 139 "client_secret": self.provider.client_secret, 140 }, 141 ) 142 self.assertEqual(response.status_code, 200) 143 body = loads(response.content.decode()) 144 self.assertEqual(body["token_type"], TOKEN_TYPE) 145 token = AccessToken.objects.filter( 146 provider=self.provider, token=body["access_token"] 147 ).first() 148 self.assertSetEqual( 149 set(token.scope), {SCOPE_OPENID, SCOPE_OPENID_EMAIL, SCOPE_OPENID_PROFILE} 150 ) 151 _, alg = self.provider.jwt_key 152 jwt = decode( 153 body["access_token"], 154 key=self.provider.signing_key.public_key, 155 algorithms=[alg], 156 audience=self.provider.client_id, 157 ) 158 self.assertEqual( 159 jwt["given_name"], "Autogenerated user from application test (client credentials)" 160 ) 161 self.assertEqual(jwt["preferred_username"], "ak-test-client_credentials") 162 jwt = decode( 163 body["id_token"], 164 key=self.provider.signing_key.public_key, 165 algorithms=[alg], 166 audience=self.provider.client_id, 167 ) 168 self.assertEqual( 169 jwt["given_name"], "Autogenerated user from application test (client credentials)" 170 ) 171 self.assertEqual(jwt["preferred_username"], "ak-test-client_credentials")
test scope that isn't configured
def
test_successful(self):
173 def test_successful(self): 174 """test successful""" 175 response = self.client.post( 176 reverse("authentik_providers_oauth2:token"), 177 { 178 "grant_type": GRANT_TYPE_CLIENT_CREDENTIALS, 179 "scope": f"{SCOPE_OPENID} {SCOPE_OPENID_EMAIL} {SCOPE_OPENID_PROFILE}", 180 "client_id": self.provider.client_id, 181 "client_secret": self.provider.client_secret, 182 }, 183 ) 184 self.assertEqual(response.status_code, 200) 185 body = loads(response.content.decode()) 186 self.assertEqual(body["token_type"], TOKEN_TYPE) 187 _, alg = self.provider.jwt_key 188 jwt = decode( 189 body["access_token"], 190 key=self.provider.signing_key.public_key, 191 algorithms=[alg], 192 audience=self.provider.client_id, 193 ) 194 self.assertEqual( 195 jwt["given_name"], "Autogenerated user from application test (client credentials)" 196 ) 197 self.assertEqual(jwt["preferred_username"], "ak-test-client_credentials") 198 jwt = decode( 199 body["id_token"], 200 key=self.provider.signing_key.public_key, 201 algorithms=[alg], 202 audience=self.provider.client_id, 203 ) 204 self.assertEqual( 205 jwt["given_name"], "Autogenerated user from application test (client credentials)" 206 ) 207 self.assertEqual(jwt["preferred_username"], "ak-test-client_credentials")
test successful
def
test_successful_password(self):
209 def test_successful_password(self): 210 """test successful (password grant)""" 211 response = self.client.post( 212 reverse("authentik_providers_oauth2:token"), 213 { 214 "grant_type": GRANT_TYPE_PASSWORD, 215 "scope": f"{SCOPE_OPENID} {SCOPE_OPENID_EMAIL} {SCOPE_OPENID_PROFILE}", 216 "client_id": self.provider.client_id, 217 "client_secret": self.provider.client_secret, 218 }, 219 ) 220 self.assertEqual(response.status_code, 200) 221 body = loads(response.content.decode()) 222 self.assertEqual(body["token_type"], TOKEN_TYPE) 223 _, alg = self.provider.jwt_key 224 jwt = decode( 225 body["access_token"], 226 key=self.provider.signing_key.public_key, 227 algorithms=[alg], 228 audience=self.provider.client_id, 229 ) 230 self.assertEqual( 231 jwt["given_name"], "Autogenerated user from application test (client credentials)" 232 ) 233 self.assertEqual(jwt["preferred_username"], "ak-test-client_credentials")
test successful (password grant)