Beispiel #1
0
    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"))
Beispiel #2
0
    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"))
Beispiel #3
0
    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
Beispiel #4
0
    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)
Beispiel #5
0
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)
Beispiel #6
0
    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
Beispiel #7
0
    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
Beispiel #8
0
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
Beispiel #9
0
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)
Beispiel #10
0
    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
Beispiel #11
0
    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
Beispiel #12
0
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')
Beispiel #13
0
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()
Beispiel #15
0
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
# ### ======================================================================