def index(self, op, **kwargs): if cherrypy.request.method == "OPTIONS": cherrypy_cors.preflight(allowed_methods=["GET"], origins='*', allowed_headers='Authorization') else: try: authz = cherrypy.request.headers['Authorization'] except KeyError: authz = None try: assert authz.startswith("Bearer") except AssertionError: op.events.store(EV_FAULT, "Bad authorization token") cherrypy.HTTPError(400, "Bad authorization token") tok = authz[7:] try: _claims = op.claim_access_token[tok] except KeyError: op.events.store(EV_FAULT, "Bad authorization token") cherrypy.HTTPError(400, "Bad authorization token") else: # one time token del op.claim_access_token[tok] _info = Message(**_claims) jwt_key = op.keyjar.get_signing_key() op.events.store(EV_RESPONSE, _info.to_dict()) cherrypy.response.headers["content-type"] = 'application/jwt' return as_bytes(_info.to_jwt(key=jwt_key, algorithm="RS256"))
def index(self, op, **kwargs): if cherrypy.request.method == "OPTIONS": cherrypy_cors.preflight( allowed_methods=["GET"], origins='*', allowed_headers='Authorization') else: try: authz = cherrypy.request.headers['Authorization'] except KeyError: authz = None try: assert authz.startswith("Bearer") except AssertionError: op.events.store(EV_FAULT, "Bad authorization token") cherrypy.HTTPError(400, "Bad authorization token") tok = authz[7:] try: _claims = op.claim_access_token[tok] except KeyError: op.events.store(EV_FAULT, "Bad authorization token") cherrypy.HTTPError(400, "Bad authorization token") else: # one time token del op.claim_access_token[tok] _info = Message(**_claims) jwt_key = op.keyjar.get_signing_key() op.events.store(EV_RESPONSE, _info.to_dict()) cherrypy.response.headers["content-type"] = 'application/jwt' return as_bytes(_info.to_jwt(key=jwt_key, algorithm="RS256"))
def _collect_user_info(self, session, userinfo_claims=None): ava = provider.Provider._collect_user_info(self, session, userinfo_claims) _src = "src1" if "aggregated" in self.claims_type: # add some aggregated claims extra = Message(eye_color="blue", shoe_size=8) _jwt = extra.to_jwt(algorithm="none") ava["_claim_names"] = Message(eye_color=_src, shoe_size=_src) a_claims = {_src: {"JWT": _jwt}} ava["_claim_sources"] = Message(**a_claims) elif "distributed" in self.claims_type: urlbase = self.name if urlbase[-1] != '/': urlbase += '/' _tok = rndstr() self.claim_access_token[_tok] = {"age": 30} ava["_claim_names"] = Message(age=_src) d_claims = { _src: {"endpoint": urlbase + "claim", "access_token": _tok}} ava["_claim_sources"] = Message(**d_claims) if "uisub" in self.behavior_type: ava["sub"] = "foobar" return ava
def index(self, op, **kwargs): if cherrypy.request.method == "OPTIONS": cherrypy_cors.preflight( allowed_methods=["GET"], origins='*', allowed_headers=['Authorization', 'content-type']) else: store_request(op, 'EndSessionRequest') logger.debug('EndSessionRequest: {}'.format(kwargs)) # op.events.store(EV_REQUEST, kwargs) cookie = cherrypy.request.cookie if cookie: logger.debug("Request cookie at end_session_endpoint: %s", cookie) _info = Message(**kwargs) if "post_logout_redirect_uri" in _info: if not 'id_token_hint' in _info: raise cherrypy.HTTPError( 400, message= "If 'post_logout_redirect_uri' then 'id_token_hint' is a MUST" ) resp = op.end_session_endpoint(_info.to_urlencoded(), cookie=cookie) # Normally the user would here be confronted with a logout # verification page. We skip that and just assumes she said yes. return conv_response(op, resp)
def msg_list_deser(val, sformat="urlencoded"): if sformat in ["dict", "json"]: if not isinstance(val, str): res = [] if sformat == "dict": for _val in val: res.append(Message().from_dict(_val)) else: for _val in val: res.append(Message().from_json(_val)) return res else: pass return Message().deserialize(val, sformat)
def gather_metadata_statements(self, context='', fos=None): """ Only gathers metadata statements and returns them. :param context: The context in which this Signed metadata statement should be used :param fos: Signed metadata statements from these Federation Operators should be added. :return: Dictionary with signed Metadata Statements as values """ if not context: context = self.def_context _res = {} if self.metadata_statements: try: cms = self.metadata_statements[context] except KeyError: if self.metadata_statements == { 'register': {}, 'discovery': {}, 'response': {} }: # No superior so an FO then. Nothing to add .. pass else: logger.error( 'No metadata statements for this context: {}'.format( context)) raise ValueError('Wrong context "{}"'.format(context)) else: if cms != {}: if fos is None: fos = list(cms.keys()) for f in fos: try: val = cms[f] except KeyError: continue if val.startswith('http'): attr = 'metadata_statement_uris' else: attr = 'metadata_statements' try: _res[attr][f] = val except KeyError: _res[attr] = Message() _res[attr][f] = val return _res
def test_get_metadata_statement(): jb = JWKSBundle('') for iss in ['https://example.org/', 'https://example.com/']: jb[iss] = build_keyjar(KEYDEFS)[1] op = Operator(keyjar=jb['https://example.com/'], iss='https://example.com/') req = MetadataStatement(foo='bar') sms = op.pack_metadata_statement(req, alg='RS256') sms_dir = {'https://example.com': sms} req['metadata_statements'] = Message(**sms_dir) ent = FederationEntity(None, fo_bundle=jb) loe = ent.get_metadata_statement(req) assert loe
def desc_deser(klass, val, sformat="urlencoded"): if sformat in ["dict", "json"]: if not isinstance(val, str): res = [] if sformat == "dict": if isinstance(val, dict): return klass().from_dict(val) elif isinstance(val, list): for _val in val: res.append(klass().from_dict(_val)) else: for _val in val: res.append(klass().from_json(_val)) return res else: pass return Message().deserialize(val, sformat)
def create_fed_providerinfo(self, pcr_class=ProviderConfigurationResponse, setup=None): _response = provider.Provider.create_providerinfo( self, pcr_class, setup) if self.ms_conf: _sms = {} for spec in self.ms_conf: self.federation_entity.signer = self.signers[spec['signer']] try: fos = spec['federations'] except KeyError: try: fos = [spec['federation']] except KeyError: fos = None _sms.update( self.create_signed_provider_info('discovery', fos=fos)) _response['metadata_statements'] = Message(**_sms) elif self.msu_conf: _sms = {} for spec in self.msu_conf: self.federation_entity.signer = self.signers[spec['signer']] try: fos = spec['federations'] except KeyError: try: fos = [spec['federation']] except KeyError: fos = None _sms.update( self.create_signed_provider_info('discovery', fos=fos)) _response = self.federation_entity.extend_with_ms(_response, _sms) return _response
def _construct_message(self, request, client, kwargs): if request: if request.__name__ == "RegistrationRequest": # don't overwrite _kwa = self._only_std(request, client.behaviour) _kwa.update(kwargs["request_args"]) kwargs["request_args"] = _kwa elif request.__name__ == "AuthorizationRequest": try: _ruri = kwargs["request_args"]["redirect_uri"] except KeyError: pass else: if _ruri == "": kwargs["request_args"]["redirect_uri"] = DUMMY_URL kwargs["target"] = client.provider_info["issuer"] cis = getattr(client, "construct_%s" % request.__name__)(request, **kwargs) # Remove parameters with None value # for key, val in cis.items(): # if val is None: # del cis[key] if isinstance(request, AuthorizationRequest) and "acr_values" not in cis: try: cis['acr_values'] = client.behaviour['default_acr_values'] except KeyError: pass setattr(self.conv, request.__name__, cis) else: cis = Message() return cis
rreq.update({ "metadata_statements": [sunet_incommon], }) rp_sunet_incommon = incommon.pack_metadata_statement(rreq, jwt_args=jwt_args) print_metadata_statement('Registration request extended by SUNET@InCommon', rp_sunet_incommon) # ---------------------------------------------------------------------------- # The RP publishes Registration Request # ---------------------------------------------------------------------------- rere = Message( redirect_uris=['https://sunet.se/rp1/callback'], metadata_statements=[rp_sunet_swamid, rp_sunet_incommon] ) print_request('Registration Request published by RP', rere) # ### ====================================================================== # # On the OP # ### ====================================================================== _jb = JWKSBundle('https://sunet.se/op') _jb[swamid.iss] = swamid.signing_keys_as_jwks() _jb[incommon.iss] = incommon.signing_keys_as_jwks() op = Operator(iss='https://sunet.se/op', jwks_bundle=_jb) print('Unpack the request')
def trace_output(lines, index, end): cont = False seq = [] _cls = None _data = [] _sent = {} _recv = {} phase = "" while index < end: line = lines[index] if cont: if line == "}": _data.append(line) cont = False _args = json.loads("".join(_data)) if _cls == "JWKS": try: _inst = jwks_load("".join(_data)) except TypeError: pass elif _cls == "UserInfo": _int = Message(**_args) try: _inst = OpenIDSchema(**_int["claims"]) except KeyError: _inst = OpenIDSchema(**_args) else: try: _inst.jwe_header = _int["jwe header parameters"] except KeyError: pass try: _inst.jws_header = _int["jws header parameters"] except KeyError: pass else: try: _inst = oic_factory(_cls)(**_args) except KeyError: _inst = oauth2_factory(_cls)(**args) seq.append((_cls, _inst)) else: _data.append(line) index += 1 continue if line == DIV: break elif line == "Trace output" or line == "": pass else: for phase in ORDER: m = PATTERN[phase].match(line) if m: if phase == "head": seq.append(m.groups()[0]) elif phase == "sent": key, val = m.groups() _sent[key] = val elif phase == "recv": key, val = m.groups() _recv[key] = val elif phase == "quer": _recv["QUERY"] = m.groups()[0] phase = "recv" elif phase == "data": m = DATA.match(line) cont = True _cls = m.groups()[0] _data = ['{'] elif phase == "tag": seq.append(("info", m.groups()[0])) if phase in ["head", "data", "end"]: if _sent: seq.append(("sent", _sent)) _sent = {} if _recv: seq.append(("recv", _recv)) _recv = {} break if phase == "end": break index += 1 return index, seq
rreq.update({ "software_statements": [dev_incommon_sost], }) rp_incommon_sost = make_software_statement(dev_swamid_keyjar, 'https://dev.example.com/', **rreq.to_dict()) # ---------------------------------------------------------------------------- # The RP publishes Registration Request # ---------------------------------------------------------------------------- rere = Message( software_statement_uris={ swamid_issuer: "https://dev.example.com/rp1/idfed/swamid.jws", incommon_issuer: "https://dev.example.com/rp1/idfed/incommon.jws" } ) print('Registration Request published by RP') print(70 * "-") print_lines(json.dumps(rere.to_dict(), sort_keys=True, indent=2, separators=(',', ': '))) # ### ====================================================================== # # On the OP # ### ====================================================================== print('The OP chooses which federation it will work under - SWAMID of course') op_keyjar = KeyJar()
rreq.update({ "software_statements": [dev_incommon_sost], }) rp_incommon_sost = make_software_statement(dev_swamid_keyjar, 'https://dev.example.com/', **rreq.to_dict()) # ---------------------------------------------------------------------------- # The RP publishes Registration Request # ---------------------------------------------------------------------------- rere = Message( software_statement_uris={ swamid_issuer: "https://dev.example.com/rp1/idfed/swamid.jws", incommon_issuer: "https://dev.example.com/rp1/idfed/incommon.jws" }) print('Registration Request published by RP') print(70 * "-") print_lines( json.dumps(rere.to_dict(), sort_keys=True, indent=2, separators=(',', ': '))) # ### ====================================================================== # # On the OP # ### ======================================================================