def read_registration(self, authn, request, **kwargs): """ Read all information this server has on a client. Authorization is done by using the access token that was return as part of the client registration result. :param authn: The Authorization HTTP header :param request: The query part of the URL :param kwargs: Any other arguments :return: """ logger.debug("authn: %s, request: %s" % (authn, request)) # verify the access token, has to be key into the client information # database. assert authn.startswith("Bearer ") token = authn[len("Bearer "):] client_id = self.cdb[token] # extra check _info = urllib.parse.parse_qs(request) assert _info["client_id"][0] == client_id logger.debug("Client '%s' reads client info" % client_id) args = dict([(k, v) for k, v in list(self.cdb[client_id].items()) if k in RegistrationResponse.c_param]) self.comb_redirect_uris(args) response = RegistrationResponse(**args) return Response(response.to_json(), content="application/json", headers=[("Cache-Control", "no-store")])
def registration(self, **kwargs): logger.debug('Request headers: {}'.format(cherrypy.request.headers)) if cherrypy.request.method == "OPTIONS": cherrypy_cors.preflight( allowed_methods=["POST", "GET"], origins='*', allowed_headers=['Authorization', 'content-type']) elif cherrypy.request.method == "GET": _cinfo = self.op.cdb[kwargs['client_id']] for attr in ['redirect_uris', 'post_logout_redirect_uris']: try: _cinfo[attr] = unpack_redirect_uri(_cinfo[attr]) except KeyError: pass rr = RegistrationResponse(**_cinfo) cherrypy.response.headers['Content-Type'] = 'application/json' return as_bytes(json.dumps(rr.to_dict())) else: logger.debug('ClientRegistration kwargs: {}'.format(kwargs)) _request = None if cherrypy.request.process_request_body is True: _request = as_unicode(cherrypy.request.body.read()) logger.debug('request_body: {}'.format(_request)) try: if _request: resp = self.op.registration_endpoint(_request) else: resp = self.op.registration_endpoint(kwargs) except Exception as err: logger.error(err) raise cherrypy.HTTPError(message=str(err)) return conv_response(resp)
def load_client_registration_info(self, client, state, key): """ Loads client registration information into the oidc client. :type client: Client :type state: dict[str, str] :type key: str :param client: oidc client :param state: A dictionary with all state values for the backend module. :param key: oidc client key """ try: redirect_uris = self.config.CLIENTS[key]["client_info"][ "redirect_uris"] except: redirect_uris = self.config.CLIENTS[key]["client_registration"][ "redirect_uris"] val = { "client_registration": { "client_id": state[StateKeys.CLIENT_ID], "client_secret": state[StateKeys.CLIENT_SECRET], "redirect_uris": redirect_uris } } client.store_registration_info( RegistrationResponse(**val["client_registration"]))
def restore_state(self, filename): txt = open(filename).read() state = json.loads(txt) self.trace.start = state["trace_log"]["start"] self.trace.trace = state["trace_log"]["trace"] self.flow_index = state["flow_index"] self.client_config = state["client_config"] self.test_output = state["test_output"] self.client.behaviour = state["client"]["behaviour"] self.client.keyjar.restore(state["client"]["keyjar"]) pcr = ProviderConfigurationResponse().from_json( state["client"]["provider_info"]) self.client.provider_info = pcr self.client.client_id = state["client"]["client_id"] self.client.client_secret = state["client"]["client_secret"] for key, val in pcr.items(): if key.endswith("_endpoint"): setattr(self.client, key, val) try: self.client.registration_response = RegistrationResponse( ).from_json(state["client"]["registration_resp"]) except KeyError: pass
def get_client(): client = Client(client_id=settings.AUTH_CLIENT_ID, client_authn_method=CLIENT_AUTHN_METHOD) client.provider_config(issuer=settings.AUTH_SERVER) client.store_registration_info( RegistrationResponse(client_id=settings.AUTH_CLIENT_ID, client_secret=settings.AUTH_CLIENT_SECRET)) return client
def run(self): if self.dynamic: self.catch_exception_and_error(self.conv.entity.register, **self.req_args) else: self.conv.events.store(EV_NOOP, "Dynamic registration") self.conv.entity.store_registration_info( RegistrationResponse( **self.conv.entity_config["registration_response"]))
def handle_registration_info(self, response): err_msg = 'Got error response: {}' unk_msg = 'Unknown response: {}' if response.status_code in [200, 201]: resp = RegistrationResponse().deserialize(response.text, "json") # Some implementations sends back a 200 with an error message inside if resp.verify(): # got a proper registration response resp = self.get_metadata_statement(resp) if resp is None: # No metadata statement that I can use raise RegistrationError('No trusted metadata') self.store_response(resp, response.text) self.store_registration_info(resp) else: resp = ErrorResponse().deserialize(response.text, "json") if resp.verify(): logger.error(err_msg.format(sanitize(resp.to_json()))) if self.events: self.events.store('protocol response', resp) raise RegistrationError(resp.to_dict()) else: # Something else logger.error(unk_msg.format(sanitize(response.text))) raise RegistrationError(response.text) else: try: resp = ErrorResponse().deserialize(response.text, "json") except _decode_err: logger.error(unk_msg.format(sanitize(response.text))) raise RegistrationError(response.text) if resp.verify(): logger.error(err_msg.format(sanitize(resp.to_json()))) if self.events: self.events.store('protocol response', resp) raise RegistrationError(resp.to_dict()) else: # Something else logger.error(unk_msg.format(sanitize(response.text))) raise RegistrationError(response.text) return resp
def load(self, filename): info = json.loads(open(filename).read()) for item in info: if isinstance(item, list): self.cdb[str(item[0])] = item[1] else: _tmp = copy.copy(item) try: for uris in ["redirect_uris", "post_logout_redirect_uris"]: try: _tmp[uris] = unpack_redirect_uri(_tmp[uris]) except KeyError: pass rr = RegistrationResponse(**_tmp) except Exception as err: print "Faulty specification: %s" % (item, ) else: self.cdb[str(item["client_id"])] = item
def __init__(self, provider_configuration, redirect_uri): """ Args: provider_configuration (flask_pyoidc.provider_configuration.ProviderConfiguration) """ self._provider_configuration = provider_configuration self._client = Client(client_authn_method=CLIENT_AUTHN_METHOD) provider_metadata = provider_configuration.ensure_provider_metadata() self._client.handle_provider_config(ProviderConfigurationResponse(**provider_metadata.to_dict()), provider_metadata['issuer']) if self._provider_configuration.registered_client_metadata: client_metadata = self._provider_configuration.registered_client_metadata.to_dict() registration_response = RegistrationResponse(**client_metadata) self._client.store_registration_info(registration_response) self._redirect_uri = redirect_uri
def client_setup(client_id, client_secret): """Sets up an OpenID Connect Relying Party ("client") for connecting to Dataporten""" logger = logging.getLogger(__name__) assert client_id, 'Missing client id when setting up Dataporten OpenID Connect Relying Party' assert client_secret, 'Missing client secret when setting up Dataporten OpenID Connect Relying Party' client = Client(client_authn_method=CLIENT_AUTHN_METHOD) logger.debug('Automatically registering Dataporten OpenID Provider.', extra={'config': DATAPORTEN_PROVIDER_CONFIG}) client.provider_config(DATAPORTEN_PROVIDER_CONFIG) client_args = { 'client_id': client_id, 'client_secret': client_secret, } client.store_registration_info(RegistrationResponse(**client_args)) logger.debug('Successfully registered the provider.') return client
def make_client(self, **kw_args): """ Have to get own copy of keyjar :param kw_args: :return: """ c_keyjar = kw_args["keyjar"].copy() args = {'client_authn_method': CLIENT_AUTHN_METHOD, 'keyjar': c_keyjar} try: args['verify_ssl'] = kw_args['verify_ssl'] except KeyError: pass else: c_keyjar.verify_ssl = kw_args['verify_ssl'] _cli = self.client_cls(**args) try: _kid = kw_args['kid'] except KeyError: pass else: kw_args['kid'] = self.adjust_kid(_kid, _cli.keyjar) c_info = {'keyjar': c_keyjar} for arg, val in list(kw_args.items()): if arg in ['keyjar']: continue setattr(_cli, arg, val) if arg == 'provider_info': _cli.handle_provider_config(val, val['issuer']) elif arg == 'registration_response': resp = RegistrationResponse(**val) _cli.store_registration_info(resp) c_info[arg] = val return _cli, c_info
def create_client(self, userid="", **kwargs): """ Do an instantiation of a client instance :param userid: An identifier of the user :param: Keyword arguments Keys are ["srv_discovery_url", "client_info", "client_registration", "provider_info"] :return: client instance """ _key_set = set(kwargs.keys()) args = {} for param in ["verify_ssl"]: try: args[param] = kwargs[param] except KeyError: pass else: _key_set.discard(param) try: verify_ssl = default_ssl_check except: verify_ssl = True client = self.client_cls(client_authn_method=CLIENT_AUTHN_METHOD, behaviour=kwargs["behaviour"], verify_ssl=verify_ssl, **args) # The behaviour parameter is not significant for the election process _key_set.discard("behaviour") for param in ["allow"]: try: setattr(client, param, kwargs[param]) except KeyError: pass else: _key_set.discard(param) if _key_set == set(["client_info"]): # Everything dynamic # There has to be a userid if not userid: raise MissingAttribute("Missing userid specification") # Find the service that provides information about the OP issuer = client.wf.discovery_query(userid) # Gather OP information client.provider_config(issuer) # register the client client.register(client.provider_info["registration_endpoint"], **kwargs["client_info"]) elif _key_set == set(["client_info", "srv_discovery_url"]): # Ship the webfinger part # Gather OP information client.provider_config(kwargs["srv_discovery_url"]) # register the client client.register(client.provider_info["registration_endpoint"], **kwargs["client_info"]) elif _key_set == set(["provider_info", "client_info"]): client.handle_provider_config( ProviderConfigurationResponse(**kwargs["provider_info"]), kwargs["provider_info"]["issuer"]) client.register(client.provider_info["registration_endpoint"], **kwargs["client_info"]) elif _key_set == set(["provider_info", "client_registration"]): client.handle_provider_config( ProviderConfigurationResponse(**kwargs["provider_info"]), kwargs["provider_info"]["issuer"]) client.store_registration_info( RegistrationResponse(**kwargs["client_registration"])) elif _key_set == set(["srv_discovery_url", "client_registration"]): try: client.provider_config(kwargs["srv_discovery_url"]) client.store_registration_info( RegistrationResponse(**kwargs["client_registration"])) except Exception as e: logger.error( "Provider info discovery failed for %s - assume backend unworkable", kwargs["srv_discovery_url"]) logger.exception(e) else: raise Exception("Configuration error ?") return client
def register(self, extra_registration_params=None): client_metadata = self._provider_configuration.register_client( [self._redirect_uri], extra_registration_params) logger.debug('client registration response: %s', client_metadata) self._client.store_registration_info( RegistrationResponse(**client_metadata.to_dict()))
def l_registration_endpoint(self, request, authn=None, **kwargs): _log_debug = logger.debug _log_info = logger.info _log_debug("@registration_endpoint") request = RegistrationRequest().deserialize(request, "json") _log_info("registration_request:%s" % request.to_dict()) resp_keys = list(request.keys()) try: request.verify() except MessageException as err: if "type" not in request: return self._error(error="invalid_type", descr="%s" % err) else: return self._error(error="invalid_configuration_parameter", descr="%s" % err) _keyjar = self.server.keyjar # create new id och secret client_id = rndstr(12) while client_id in self.cdb: client_id = rndstr(12) client_secret = secret(self.seed, client_id) _rat = rndstr(32) reg_enp = "" for endp in self.endpoints: if isinstance(endp, DynamicClientEndpoint): reg_enp = "%s%s" % (self.baseurl, endp.etype) self.cdb[client_id] = { "client_id": client_id, "client_secret": client_secret, "registration_access_token": _rat, "registration_client_uri": "%s?client_id=%s" % (reg_enp, client_id), "client_secret_expires_at": utc_time_sans_frac() + 86400, "client_id_issued_at": utc_time_sans_frac()} self.cdb[_rat] = client_id _cinfo = self.do_client_registration(request, client_id, ignore=["redirect_uris", "policy_url", "logo_url"]) if isinstance(_cinfo, Response): return _cinfo args = dict([(k, v) for k, v in list(_cinfo.items()) if k in RegistrationResponse.c_param]) self.comb_redirect_uris(args) response = RegistrationResponse(**args) self.keyjar.load_keys(request, client_id) # Add the key to the keyjar if client_secret: _kc = KeyBundle([{"kty": "oct", "key": client_secret, "use": "ver"}, {"kty": "oct", "key": client_secret, "use": "sig"}]) try: _keyjar[client_id].append(_kc) except KeyError: _keyjar[client_id] = [_kc] self.cdb[client_id] = _cinfo _log_info("Client info: %s" % _cinfo) logger.debug("registration_response: %s" % response.to_dict()) return Response(response.to_json(), content="application/json", headers=[("Cache-Control", "no-store")])
def create_client(**kwargs): """ kwargs = config.CLIENT.iteritems """ _key_set = set(kwargs.keys()) args = {} for param in ["verify_ssl", "client_id", "client_secret"]: try: args[param] = kwargs[param] except KeyError: try: args[param] = kwargs['client_registration'][param] except KeyError: pass else: _key_set.discard(param) client = Client(client_authn_method=CLIENT_AUTHN_METHOD, behaviour=kwargs["behaviour"], verify_ssl=conf.VERIFY_SSL, **args) # The behaviour parameter is not significant for the election process _key_set.discard("behaviour") # I do not understand how this was ever working without discarding this # Below is not a case where _key_set includes "registration_response" _key_set.discard("registration_response") for param in ["allow"]: try: setattr(client, param, kwargs[param]) except KeyError: pass else: _key_set.discard(param) if _key_set == set(["client_info"]): # Everything dynamic # There has to be a userid if not userid: raise MissingAttribute("Missing userid specification") # Find the service that provides information about the OP issuer = client.wf.discovery_query(userid) # Gather OP information _ = client.provider_config(issuer) # register the client _ = client.register(client.provider_info["registration_endpoint"], **kwargs["client_info"]) elif _key_set == set(["client_info", "srv_discovery_url"]): # Ship the webfinger part # Gather OP information _ = client.provider_config(kwargs["srv_discovery_url"]) # register the client _ = client.register(client.provider_info["registration_endpoint"], **kwargs["client_info"]) elif _key_set == set(["provider_info", "client_info"]): client.handle_provider_config( ProviderConfigurationResponse(**kwargs["provider_info"]), kwargs["provider_info"]["issuer"]) _ = client.register(client.provider_info["registration_endpoint"], **kwargs["client_info"]) elif _key_set == set(["provider_info", "client_registration"]): client.handle_provider_config( ProviderConfigurationResponse(**kwargs["provider_info"]), kwargs["provider_info"]["issuer"]) client.store_registration_info( RegistrationResponse(**kwargs["client_registration"])) elif _key_set == set(["srv_discovery_url", "client_registration"]): _ = client.provider_config(kwargs["srv_discovery_url"]) client.store_registration_info( RegistrationResponse(**kwargs["client_registration"])) else: raise Exception("Configuration error ?") return client
def create_client(self, userid="", **kwargs): """ Do an instantiation of a client instance. :param userid: An identifier of the user :param: Keyword arguments Keys are ["srv_discovery_url", "client_info", "client_registration", "provider_info"] :return: client instance """ _key_set = set(list(kwargs.keys())) try: _verify_ssl = kwargs["verify_ssl"] except KeyError: _verify_ssl = self.verify_ssl else: _key_set.discard("verify_ssl") client = self.client_cls( client_authn_method=CLIENT_AUTHN_METHOD, behaviour=kwargs["behaviour"], verify_ssl=_verify_ssl, ) try: client.userinfo_request_method = kwargs["userinfo_request_method"] except KeyError: pass else: _key_set.discard("userinfo_request_method") # The behaviour parameter is not significant for the election process _key_set.discard("behaviour") for param in ["allow"]: try: setattr(client, param, kwargs[param]) except KeyError: pass else: _key_set.discard(param) if _key_set == {"client_info"}: # Everything dynamic # There has to be a userid if not userid: raise MissingAttribute("Missing userid specification") # Find the service that provides information about the OP issuer = client.wf.discovery_query(userid) # Gather OP information client.provider_config(issuer) # register the client client.register( client.provider_info["registration_endpoint"], **kwargs["client_info"] ) self.get_path(kwargs["client_info"]["redirect_uris"], issuer) elif _key_set == set(["client_info", "srv_discovery_url"]): # Ship the webfinger part # Gather OP information client.provider_config(kwargs["srv_discovery_url"]) # register the client client.register( client.provider_info["registration_endpoint"], **kwargs["client_info"] ) self.get_path( kwargs["client_info"]["redirect_uris"], kwargs["srv_discovery_url"] ) elif _key_set == set(["provider_info", "client_info"]): client.handle_provider_config( ProviderConfigurationResponse(**kwargs["provider_info"]), kwargs["provider_info"]["issuer"], ) client.register( client.provider_info["registration_endpoint"], **kwargs["client_info"] ) self.get_path( kwargs["client_info"]["redirect_uris"], kwargs["provider_info"]["issuer"], ) elif _key_set == set(["provider_info", "client_registration"]): client.handle_provider_config( ProviderConfigurationResponse(**kwargs["provider_info"]), kwargs["provider_info"]["issuer"], ) client.store_registration_info( RegistrationResponse(**kwargs["client_registration"]) ) self.get_path( kwargs["client_info"]["redirect_uris"], kwargs["provider_info"]["issuer"], ) elif _key_set == set(["srv_discovery_url", "client_registration"]): client.provider_config(kwargs["srv_discovery_url"]) client.store_registration_info( RegistrationResponse(**kwargs["client_registration"]) ) self.get_path( kwargs["client_registration"]["redirect_uris"], kwargs["srv_discovery_url"], ) else: raise Exception("Configuration error ?") return client
def __call__(self): if self.dynamic: self.catch_exception(self.conv.client.register, **self.req_args) else: self.conv.client.store_registration_info( RegistrationResponse(**self.conf.INFO["registered"]))
def l_registration_endpoint(self, request, authn=None, **kwargs): _log_debug = logger.debug _log_info = logger.info _log_debug("@registration_endpoint") request = RegistrationRequest().deserialize(request, "json") _log_info("registration_request:%s" % request.to_dict()) resp_keys = list(request.keys()) try: request.verify() except MessageException as err: if "type" not in request: return self._error(error="invalid_type", descr="%s" % err) else: return self._error(error="invalid_configuration_parameter", descr="%s" % err) _keyjar = self.server.keyjar # create new id och secret client_id = rndstr(12) while client_id in self.cdb: client_id = rndstr(12) client_secret = secret(self.seed, client_id) _rat = rndstr(32) reg_enp = "" for endp in self.endpoints: if isinstance(endp, DynamicClientEndpoint): reg_enp = "%s%s" % (self.baseurl, endp.etype) self.cdb[client_id] = { "client_id": client_id, "client_secret": client_secret, "registration_access_token": _rat, "registration_client_uri": "%s?client_id=%s" % (reg_enp, client_id), "client_secret_expires_at": utc_time_sans_frac() + 86400, "client_id_issued_at": utc_time_sans_frac() } self.cdb[_rat] = client_id _cinfo = self.do_client_registration( request, client_id, ignore=["redirect_uris", "policy_url", "logo_url"]) if isinstance(_cinfo, Response): return _cinfo args = dict([(k, v) for k, v in list(_cinfo.items()) if k in RegistrationResponse.c_param]) self.comb_redirect_uris(args) response = RegistrationResponse(**args) self.keyjar.load_keys(request, client_id) # Add the key to the keyjar if client_secret: _kc = KeyBundle([{ "kty": "oct", "key": client_secret, "use": "ver" }, { "kty": "oct", "key": client_secret, "use": "sig" }]) try: _keyjar[client_id].append(_kc) except KeyError: _keyjar[client_id] = [_kc] self.cdb[client_id] = _cinfo _log_info("Client info: %s" % _cinfo) logger.debug("registration_response: %s" % response.to_dict()) return Response(response.to_json(), content="application/json", headers=[("Cache-Control", "no-store")])
callback = "%s/%s" % (RS_HOST, "auth_cb") _me = { "application_type": "web", "application_name": "umaclient", "contacts": ["*****@*****.**"], "redirect_uris": [callback] } ressrv.client.redirect_uris = [callback] # Register the RS as a client to the AS, this is OAuth2 dynreg registration reg_info = ressrv.client.construct_RegistrationRequest(request_args=_me) reg_resp = authzsrv.oauth_registration_endpoint(reg_info.to_json()) regresp = RegistrationResponse().from_json(reg_resp.message) ressrv.client.store_registration_info(regresp) # Get the PAT, should normally be a login and token request RESOURCE_OWNER = "linda" identity = {"uid": RESOURCE_OWNER} areq = AuthorizationRequest(client_id=regresp["client_id"], scope=[PAT]) # Authentication happens by magic :-) authn_event = AuthnEvent(RESOURCE_OWNER, 'salt', authn_info="UserPassword", time_stamp=int(time.time())) sid = authzsrv.sdb.create_authz_session(authn_event, areq) grant = authzsrv.sdb[sid]["code"] _dict = authzsrv.sdb.upgrade_to_token(grant)
self.wfile.write(json.dumps(content).encode("UTF-8")) if __name__ == "__main__": parser = argparse.ArgumentParser("get_tokens", description="Retrieves access and id tokens from Mafiasi Identity") parser.add_argument("--issuer", help="OpenId Connect issuer. Defaults to Mafiasi", default="https://identity.mafiasi.de/auth/realms/mafiasi") parser.add_argument("--client-id", help="OpenId Connect client id. Defaults to dev-client", default="dev-client") parser.add_argument("--client-secret", help="OpenId Connect client secret. Defaults to dev-client's secret", default="bb0c83bc-1dd9-4946-a074-d452bc1fb830") parser.add_argument("--scope", help="OpenID scopes to request", action="append", default=["openid"]) cmd_args = parser.parse_args() # initialize openid client client = Client(client_id=cmd_args.client_id, client_authn_method=CLIENT_AUTHN_METHOD) client.provider_config(cmd_args.issuer) client.store_registration_info(RegistrationResponse(client_id=cmd_args.client_id, client_secret=cmd_args.client_secret)) # initialize a session object (which is very primitive but works) session = defaultdict(lambda: "") # serve a basic http server so that authorization code flow can be used with HTTPServer(("127.0.0.1", 8080), RequestHandler) as server: print(f"Open http://{server.server_name}:{server.server_port}") try: server.serve_forever() except KeyboardInterrupt: pass