authentik.sources.oauth.tests.test_type_openid
OpenID Type tests
1"""OpenID Type tests""" 2 3import time 4 5from django.test import RequestFactory, TestCase 6from jwt import encode 7from requests_mock import Mocker 8 9from authentik.core.tests.utils import create_test_cert 10from authentik.lib.generators import generate_id 11from authentik.providers.oauth2.views.jwks import JWKSView 12from authentik.sources.oauth.models import OAuthSource 13from authentik.sources.oauth.types.oidc import OpenIDConnectOAuth2Callback, OpenIDConnectType 14 15# https://connect2id.com/products/server/docs/api/userinfo 16OPENID_USER = { 17 "sub": "83692", 18 "name": "Alice Adams", 19 "email": "alice@example.com", 20 "department": "Engineering", 21 "birthdate": "1975-12-31", 22 "nickname": "foo", 23} 24 25 26class TestTypeOpenID(TestCase): 27 """OAuth Source tests""" 28 29 def setUp(self): 30 self.source = OAuthSource.objects.create( 31 name="test", 32 slug="test", 33 provider_type="openidconnect", 34 authorization_url="", 35 profile_url="http://localhost/userinfo", 36 consumer_key="", 37 ) 38 self.factory = RequestFactory() 39 40 def test_enroll_context(self): 41 """Test OpenID Enrollment context""" 42 ak_context = OpenIDConnectType().get_base_user_properties( 43 source=self.source, info=OPENID_USER 44 ) 45 self.assertEqual(ak_context["username"], OPENID_USER["nickname"]) 46 self.assertEqual(ak_context["email"], OPENID_USER["email"]) 47 self.assertEqual(ak_context["name"], OPENID_USER["name"]) 48 49 @Mocker() 50 def test_userinfo(self, mock: Mocker): 51 """Test userinfo API call""" 52 mock.get("http://localhost/userinfo", json=OPENID_USER) 53 token = generate_id() 54 OpenIDConnectOAuth2Callback(request=self.factory.get("/")).get_client( 55 self.source 56 ).get_profile_info( 57 { 58 "token_type": "foo", 59 "access_token": token, 60 } 61 ) 62 self.assertEqual(mock.last_request.query, "") 63 self.assertEqual(mock.last_request.headers["Authorization"], f"foo {token}") 64 65 @Mocker() 66 def test_userinfo_jwt(self, mock: Mocker): 67 """Test id_token fallback when profile_url is empty""" 68 jwks_cert = create_test_cert() 69 client_id = generate_id() 70 self.source.profile_url = "" 71 self.source.consumer_key = client_id 72 self.source.oidc_jwks = {"keys": [JWKSView.get_jwk_for_key(jwks_cert, "sig")]} 73 self.source.save() 74 token = generate_id() 75 now = int(time.time()) 76 id_token_payload = { 77 "iss": "https://example.com", 78 "sub": OPENID_USER["sub"], 79 "aud": client_id, 80 "exp": now + 3600, 81 "iat": now, 82 "name": OPENID_USER["name"], 83 "email": OPENID_USER["email"], 84 "nickname": OPENID_USER["nickname"], 85 } 86 profile = ( 87 OpenIDConnectOAuth2Callback(request=self.factory.get("/")) 88 .get_client(self.source) 89 .get_profile_info( 90 { 91 "token_type": "Bearer", 92 "access_token": token, 93 "id_token": encode( 94 id_token_payload, 95 key=jwks_cert.private_key, 96 algorithm="RS256", 97 headers={"kid": self.source.oidc_jwks["keys"][0]["kid"]}, 98 ), 99 } 100 ) 101 ) 102 self.assertEqual(profile["sub"], OPENID_USER["sub"]) 103 self.assertEqual(profile["name"], OPENID_USER["name"]) 104 self.assertEqual(profile["email"], OPENID_USER["email"]) 105 self.assertEqual(profile["aud"], client_id) 106 self.assertEqual(profile["iss"], "https://example.com")
OPENID_USER =
{'sub': '83692', 'name': 'Alice Adams', 'email': 'alice@example.com', 'department': 'Engineering', 'birthdate': '1975-12-31', 'nickname': 'foo'}
class
TestTypeOpenID(django.test.testcases.TestCase):
27class TestTypeOpenID(TestCase): 28 """OAuth Source tests""" 29 30 def setUp(self): 31 self.source = OAuthSource.objects.create( 32 name="test", 33 slug="test", 34 provider_type="openidconnect", 35 authorization_url="", 36 profile_url="http://localhost/userinfo", 37 consumer_key="", 38 ) 39 self.factory = RequestFactory() 40 41 def test_enroll_context(self): 42 """Test OpenID Enrollment context""" 43 ak_context = OpenIDConnectType().get_base_user_properties( 44 source=self.source, info=OPENID_USER 45 ) 46 self.assertEqual(ak_context["username"], OPENID_USER["nickname"]) 47 self.assertEqual(ak_context["email"], OPENID_USER["email"]) 48 self.assertEqual(ak_context["name"], OPENID_USER["name"]) 49 50 @Mocker() 51 def test_userinfo(self, mock: Mocker): 52 """Test userinfo API call""" 53 mock.get("http://localhost/userinfo", json=OPENID_USER) 54 token = generate_id() 55 OpenIDConnectOAuth2Callback(request=self.factory.get("/")).get_client( 56 self.source 57 ).get_profile_info( 58 { 59 "token_type": "foo", 60 "access_token": token, 61 } 62 ) 63 self.assertEqual(mock.last_request.query, "") 64 self.assertEqual(mock.last_request.headers["Authorization"], f"foo {token}") 65 66 @Mocker() 67 def test_userinfo_jwt(self, mock: Mocker): 68 """Test id_token fallback when profile_url is empty""" 69 jwks_cert = create_test_cert() 70 client_id = generate_id() 71 self.source.profile_url = "" 72 self.source.consumer_key = client_id 73 self.source.oidc_jwks = {"keys": [JWKSView.get_jwk_for_key(jwks_cert, "sig")]} 74 self.source.save() 75 token = generate_id() 76 now = int(time.time()) 77 id_token_payload = { 78 "iss": "https://example.com", 79 "sub": OPENID_USER["sub"], 80 "aud": client_id, 81 "exp": now + 3600, 82 "iat": now, 83 "name": OPENID_USER["name"], 84 "email": OPENID_USER["email"], 85 "nickname": OPENID_USER["nickname"], 86 } 87 profile = ( 88 OpenIDConnectOAuth2Callback(request=self.factory.get("/")) 89 .get_client(self.source) 90 .get_profile_info( 91 { 92 "token_type": "Bearer", 93 "access_token": token, 94 "id_token": encode( 95 id_token_payload, 96 key=jwks_cert.private_key, 97 algorithm="RS256", 98 headers={"kid": self.source.oidc_jwks["keys"][0]["kid"]}, 99 ), 100 } 101 ) 102 ) 103 self.assertEqual(profile["sub"], OPENID_USER["sub"]) 104 self.assertEqual(profile["name"], OPENID_USER["name"]) 105 self.assertEqual(profile["email"], OPENID_USER["email"]) 106 self.assertEqual(profile["aud"], client_id) 107 self.assertEqual(profile["iss"], "https://example.com")
OAuth Source tests
def
setUp(self):
30 def setUp(self): 31 self.source = OAuthSource.objects.create( 32 name="test", 33 slug="test", 34 provider_type="openidconnect", 35 authorization_url="", 36 profile_url="http://localhost/userinfo", 37 consumer_key="", 38 ) 39 self.factory = RequestFactory()
Hook method for setting up the test fixture before exercising it.
def
test_enroll_context(self):
41 def test_enroll_context(self): 42 """Test OpenID Enrollment context""" 43 ak_context = OpenIDConnectType().get_base_user_properties( 44 source=self.source, info=OPENID_USER 45 ) 46 self.assertEqual(ak_context["username"], OPENID_USER["nickname"]) 47 self.assertEqual(ak_context["email"], OPENID_USER["email"]) 48 self.assertEqual(ak_context["name"], OPENID_USER["name"])
Test OpenID Enrollment context
@Mocker()
def
test_userinfo(self, mock: requests_mock.mocker.Mocker):
50 @Mocker() 51 def test_userinfo(self, mock: Mocker): 52 """Test userinfo API call""" 53 mock.get("http://localhost/userinfo", json=OPENID_USER) 54 token = generate_id() 55 OpenIDConnectOAuth2Callback(request=self.factory.get("/")).get_client( 56 self.source 57 ).get_profile_info( 58 { 59 "token_type": "foo", 60 "access_token": token, 61 } 62 ) 63 self.assertEqual(mock.last_request.query, "") 64 self.assertEqual(mock.last_request.headers["Authorization"], f"foo {token}")
Test userinfo API call
@Mocker()
def
test_userinfo_jwt(self, mock: requests_mock.mocker.Mocker):
66 @Mocker() 67 def test_userinfo_jwt(self, mock: Mocker): 68 """Test id_token fallback when profile_url is empty""" 69 jwks_cert = create_test_cert() 70 client_id = generate_id() 71 self.source.profile_url = "" 72 self.source.consumer_key = client_id 73 self.source.oidc_jwks = {"keys": [JWKSView.get_jwk_for_key(jwks_cert, "sig")]} 74 self.source.save() 75 token = generate_id() 76 now = int(time.time()) 77 id_token_payload = { 78 "iss": "https://example.com", 79 "sub": OPENID_USER["sub"], 80 "aud": client_id, 81 "exp": now + 3600, 82 "iat": now, 83 "name": OPENID_USER["name"], 84 "email": OPENID_USER["email"], 85 "nickname": OPENID_USER["nickname"], 86 } 87 profile = ( 88 OpenIDConnectOAuth2Callback(request=self.factory.get("/")) 89 .get_client(self.source) 90 .get_profile_info( 91 { 92 "token_type": "Bearer", 93 "access_token": token, 94 "id_token": encode( 95 id_token_payload, 96 key=jwks_cert.private_key, 97 algorithm="RS256", 98 headers={"kid": self.source.oidc_jwks["keys"][0]["kid"]}, 99 ), 100 } 101 ) 102 ) 103 self.assertEqual(profile["sub"], OPENID_USER["sub"]) 104 self.assertEqual(profile["name"], OPENID_USER["name"]) 105 self.assertEqual(profile["email"], OPENID_USER["email"]) 106 self.assertEqual(profile["aud"], client_id) 107 self.assertEqual(profile["iss"], "https://example.com")
Test id_token fallback when profile_url is empty