44import traceback
55
66from cryptojwt .key_bundle import keybundle_from_local_file
7+ from cryptojwt .key_jar import init_key_jar
78from cryptojwt .utils import as_bytes
89from cryptojwt .utils import as_unicode
910from oidcmsg .exception import MessageException
@@ -54,6 +55,53 @@ def token_secret_key(sid):
5455SERVICE_NAME = "OIC"
5556CLIENT_CONFIG = {}
5657
58+ DEFAULT_SEVICES = {
59+ 'web_finger' : {'class' : 'oidcservice.oidc.webfinger.WebFinger' },
60+ 'discovery' : {'class' : 'oidcservice.oidc.provider_info_discovery.ProviderInfoDiscovery' },
61+ 'registration' : {'class' : 'oidcservice.oidc.registration.Registration' },
62+ 'authorization' : {'class' : 'oidcservice.oidc.authorization.Authorization' },
63+ 'access_token' : {'class' : 'oidcservice.oidc.access_token.AccessToken' },
64+ 'refresh_access_token' : {'class' : 'oidcservice.oidc.refresh_access_token.RefreshAccessToken' },
65+ 'userinfo' : {'class' : 'oidcservice.oidc.userinfo.UserInfo' }
66+ }
67+
68+ DEFAULT_CLIENT_PREFS = {
69+ 'application_type' : 'web' ,
70+ 'application_name' : 'rphandler' ,
71+ 'response_types' : ['code' , 'id_token' , 'id_token token' , 'code id_token' , 'code id_token token' ,
72+ 'code token' ],
73+ 'scope' : ['openid' ],
74+ 'token_endpoint_auth_method' : 'client_secret_basic'
75+ }
76+
77+ # Using PKCE is default
78+ DEFAULT_CLIENT_CONFIGS = {
79+ "" : {
80+ "client_preferences" : DEFAULT_CLIENT_PREFS ,
81+ "add_ons" : {
82+ "pkce" : {
83+ "function" : "oidcservice.oidc.add_on.pkce.add_pkce_support" ,
84+ "kwargs" : {
85+ "code_challenge_length" : 64 ,
86+ "code_challenge_method" : "S256"
87+ }
88+ }
89+ }
90+ }
91+ }
92+
93+ DEFAULT_KEY_DEFS = [
94+ {"type" : "RSA" , "use" : ["sig" ]},
95+ {"type" : "EC" , "crv" : "P-256" , "use" : ["sig" ]},
96+ ]
97+
98+ DEFAULT_RP_KEY_DEFS = {
99+ 'private_path' : 'private/jwks.json' ,
100+ 'key_defs' : DEFAULT_KEY_DEFS ,
101+ 'public_path' : 'static/jwks.json' ,
102+ 'read_only' : False
103+ }
104+
57105
58106def add_path (url , path ):
59107 if url .endswith ('/' ):
@@ -113,14 +161,30 @@ def dynamic_provider_info_discovery(client):
113161
114162
115163class RPHandler (object ):
116- def __init__ (self , base_url = '' , hash_seed = "" , keyjar = None , verify_ssl = True ,
117- services = None , client_configs = None , client_authn_factory = None ,
164+ def __init__ (self , base_url , client_configs = None , services = None , keyjar = None ,
165+ hash_seed = "" , verify_ssl = True , client_authn_factory = None ,
118166 client_cls = None , state_db = None , http_lib = None , httpc_params = None ,
119167 ** kwargs ):
120168
121169 self .base_url = base_url
122- self .hash_seed = as_bytes (hash_seed )
123- self .keyjar = keyjar
170+ if hash_seed :
171+ self .hash_seed = as_bytes (hash_seed )
172+ else :
173+ self .hash_seed = as_bytes (rndstr (32 ))
174+
175+ _jwks_path = kwargs .get ('jwks_path' )
176+ if keyjar is None :
177+ self .keyjar = init_key_jar (** DEFAULT_RP_KEY_DEFS , owner = '' )
178+ self .keyjar .import_jwks_as_json (self .keyjar .export_jwks_as_json (True , '' ), base_url )
179+ if _jwks_path is None :
180+ _jwks_path = DEFAULT_RP_KEY_DEFS ['public_path' ]
181+ else :
182+ self .keyjar = keyjar
183+
184+ try :
185+ self .jwks_uri = add_path (base_url , _jwks_path )
186+ except KeyError :
187+ self .jwks_uri = ""
124188
125189 if state_db :
126190 self .state_db = state_db
@@ -129,22 +193,26 @@ def __init__(self, base_url='', hash_seed="", keyjar=None, verify_ssl=True,
129193
130194 self .session_interface = StateInterface (self .state_db )
131195
132- try :
133- self .jwks_uri = add_path (base_url , kwargs ['jwks_path' ])
134- except KeyError :
135- self .jwks_uri = ""
136-
137196 self .extra = kwargs
138197
139198 self .client_cls = client_cls or oidc .RP
140- self .services = services
199+ if services is None :
200+ self .services = DEFAULT_SEVICES
201+ else :
202+ self .services = services
203+
141204 self .client_authn_factory = client_authn_factory
142- self .client_configs = client_configs
205+
206+ if client_configs is None :
207+ self .client_configs = DEFAULT_CLIENT_CONFIGS
208+ else :
209+ self .client_configs = client_configs
143210
144211 # keep track on which RP instance that serves with OP
145212 self .issuer2rp = {}
146213 self .hash2issuer = {}
147214 self .httplib = http_lib
215+
148216 if not httpc_params :
149217 self .httpc_params = {'verify' : verify_ssl }
150218 else :
@@ -193,7 +261,12 @@ def init_client(self, issuer):
193261 :param issuer: An issuer ID
194262 :return: A Client instance
195263 """
196- _cnf = self .pick_config (issuer )
264+ try :
265+ _cnf = self .pick_config (issuer )
266+ except KeyError :
267+ _cnf = self .pick_config ('' )
268+ _cnf ['issuer' ] = issuer
269+
197270 try :
198271 _services = _cnf ['services' ]
199272 except KeyError :
@@ -310,6 +383,13 @@ def do_client_registration(self, client=None, iss_id='', state=''):
310383 if not client .service_context .client_id :
311384 load_registration_response (client )
312385
386+ def add_callbacks (self , service_context ):
387+ _callbacks = self .create_callbacks (service_context .provider_info ['issuer' ])
388+ service_context .redirect_uris = [
389+ v for k , v in _callbacks .items () if not k .startswith ('__' )]
390+ service_context .callbacks = _callbacks
391+ return _callbacks
392+
313393 def client_setup (self , iss_id = '' , user = '' ):
314394 """
315395 First if no issuer ID is given then the identifier for the user is
@@ -365,10 +445,7 @@ def client_setup(self, iss_id='', user=''):
365445 _sc .client_id = client .client_id = add_path (_fe .entity_id , iss_id )
366446 self .hash2issuer [iss_id ] = issuer
367447 else :
368- _callbacks = self .create_callbacks (_sc .provider_info ['issuer' ])
369- _sc .redirect_uris = [
370- v for k , v in _callbacks .items () if not k .startswith ('__' )]
371- _sc .callbacks = _callbacks
448+ _callbacks = self .add_callbacks (_sc )
372449 _sc .client_id = client .client_id = add_path (_fe .entity_id , _callbacks ['__hex' ])
373450 else : # explicit
374451 logger .debug ("Do client registration" )
0 commit comments