Example #1
0
    def openid_conf(self):
        endpoint = {}
        for point, path in ENDPOINT.items():
            endpoint[point] = "%s%s" % (self.host, path)

        signing_algs = list(jws.SIGNER_ALGS.keys())
        resp = ProviderConfigurationResponse(
            issuer=self.name,
            scopes_supported=["openid", "profile", "email", "address"],
            identifiers_supported=["public", "PPID"],
            flows_supported=[
                "code", "token", "code token", "id_token", "code id_token",
                "token id_token"
            ],
            subject_types_supported=["pairwise", "public"],
            response_types_supported=[
                "code", "token", "id_token", "code token", "code id_token",
                "token id_token", "code token id_token"
            ],
            jwks_uri="http://example.com/oidc/jwks",
            id_token_signing_alg_values_supported=signing_algs,
            grant_types_supported=["authorization_code", "implicit"],
            **endpoint)

        response = Response()
        response.headers = {"content-type": "application/json"}
        response.text = resp.to_json()
        return response
Example #2
0
    def test_provider_configuration_endpoint(self, context, frontend):
        expected_capabilities = {
            "response_types_supported": ["code", "id_token", "code id_token token"],
            "jwks_uri": "{}/{}/jwks".format(BASE_URL, frontend.name),
            "authorization_endpoint": "{}/foo_backend/{}/authorization".format(BASE_URL, frontend.name),
            "token_endpoint": "{}/{}/token".format(BASE_URL, frontend.name),
            "userinfo_endpoint": "{}/{}/userinfo".format(BASE_URL, frontend.name),
            "id_token_signing_alg_values_supported": ["RS256"],
            "response_modes_supported": ["fragment", "query"],
            "subject_types_supported": ["pairwise"],
            "claim_types_supported": ["normal"],
            "claims_parameter_supported": True,
            "request_parameter_supported": False,
            "request_uri_parameter_supported": False,
            "scopes_supported": ["openid", "email"],
            "claims_supported": ["email"],
            "grant_types_supported": ["authorization_code", "implicit"],
            "issuer": BASE_URL,
            "require_request_uri_registration": True,
            "token_endpoint_auth_methods_supported": ["client_secret_basic"],
            "version": "3.0",
        }

        http_response = frontend.provider_config(context)
        provider_config = ProviderConfigurationResponse().deserialize(http_response.message, "json")

        assert provider_config.to_dict() == expected_capabilities
Example #3
0
    def provider_config(self, issuer, keys=True, endpoints=True):
        if issuer.endswith("/"):
            _issuer = issuer[:-1]
        else:
            _issuer = issuer

        url = OIDCONF_PATTERN % _issuer

        r = self.http_request(url)
        if r.status_code == 200:
            pcr = ProviderConfigurationResponse().from_json(r.text)
        else:
            raise Exception("Trying '%s', status %s" % (url, r.status_code))

        if "issuer" in pcr:
            if pcr["issuer"].endswith("/"):
                _pcr_issuer = pcr["issuer"][:-1]
            else:
                _pcr_issuer = pcr["issuer"]

            try:
                assert _issuer == _pcr_issuer
            except AssertionError:
                raise Exception("provider info issuer mismatch '%s' != '%s'" % (
                    _issuer, _pcr_issuer))

        if endpoints:
            for key, val in pcr.items():
                if key.endswith("_endpoint"):
                    setattr(self, key, val)

        if keys:
            self.keystore.load_keys(pcr, _issuer)

        return pcr
Example #4
0
    def test_provider_configuration_endpoint(self, context, frontend):
        expected_capabilities = {
            "response_types_supported": ["code", "id_token", "code id_token token"],
            "jwks_uri": "{}/{}/jwks".format(BASE_URL, frontend.name),
            "authorization_endpoint": "{}/foo_backend/{}/authorization".format(BASE_URL, frontend.name),
            "token_endpoint": "{}/{}/token".format(BASE_URL, frontend.name),
            "userinfo_endpoint": "{}/{}/userinfo".format(BASE_URL, frontend.name),
            "id_token_signing_alg_values_supported": ["RS256"],
            "response_modes_supported": ["fragment", "query"],
            "subject_types_supported": ["pairwise"],
            "claim_types_supported": ["normal"],
            "claims_parameter_supported": True,
            "request_parameter_supported": False,
            "request_uri_parameter_supported": False,
            "claims_supported": ["email"],
            "grant_types_supported": ["authorization_code", "implicit"],
            "issuer": BASE_URL,
            "require_request_uri_registration": False,
            "token_endpoint_auth_methods_supported": ["client_secret_basic"],
            "version": "3.0"
        }

        http_response = frontend.provider_config(context)
        provider_config = ProviderConfigurationResponse().deserialize(http_response.message, "json")

        provider_config_dict = provider_config.to_dict()
        scopes_supported = provider_config_dict.pop("scopes_supported")
        assert all(scope in scopes_supported for scope in ["openid", "email"])
        assert provider_config_dict == expected_capabilities
Example #5
0
    def openid_conf(self):
        endpoint = {}
        for point, path in ENDPOINT.items():
            endpoint[point] = "%s%s" % (self.host, path)

        signing_algs = list(jws.SIGNER_ALGS.keys())
        resp = ProviderConfigurationResponse(
            issuer=self.name,
            scopes_supported=["openid", "profile", "email", "address"],
            identifiers_supported=["public", "PPID"],
            flows_supported=["code", "token", "code token", "id_token",
                             "code id_token", "token id_token"],
            subject_types_supported=["pairwise", "public"],
            response_types_supported=["code", "token", "id_token",
                                      "code token", "code id_token",
                                      "token id_token", "code token id_token"],
            jwks_uri="http://example.com/oidc/jwks",
            id_token_signing_alg_values_supported=signing_algs,
            grant_types_supported=["authorization_code", "implicit"],
            **endpoint)

        response = Response()
        response.headers = {"content-type": "application/json"}
        response.text = resp.to_json()
        return response
def test_example_response():
    resp = {
        "version": "3.0",
        "issuer": "https://server.example.com",
        "authorization_endpoint":
            "https://server.example.com/connect/authorize",
        "token_endpoint": "https://server.example.com/connect/token",
        "token_endpoint_auth_methods_supported": ["client_secret_basic",
                                                  "private_key_jwt"],
        "token_endpoint_alg_values_supported": ["RS256", "ES256"],
        "userinfo_endpoint": "https://server.example.com/connect/userinfo",
        "check_session_iframe":
            "https://server.example.com/connect/check_session",
        "end_session_endpoint":
            "https://server.example.com/connect/end_session",
        "jwks_uri": "https://server.example.com/jwks.json",
        "registration_endpoint": "https://server.example.com/connect/register",
        "scopes_supported": ["openid", "profile", "email", "address",
                             "phone", "offline_access"],
        "response_types_supported": ["code", "code id_token", "id_token",
                                     "token id_token"],
        "acr_values_supported": ["urn:mace:incommon:iap:silver",
                                 "urn:mace:incommon:iap:bronze"],
        "subject_types_supported": ["public", "pairwise"],
        "userinfo_signing_alg_values_supported": ["RS256", "ES256", "HS256"],
        "userinfo_encryption_alg_values_supported": ["RSA1_5", "A128KW"],
        "userinfo_encryption_enc_values_supported": ["A128CBC+HS256",
                                                     "A128GCM"],
        "id_token_signing_alg_values_supported": ["RS256", "ES256", "HS256"],
        "id_token_encryption_alg_values_supported": ["RSA1_5", "A128KW"],
        "id_token_encryption_enc_values_supported": ["A128CBC+HS256",
                                                     "A128GCM"],
        "request_object_signing_alg_values_supported": ["none", "RS256",
                                                        "ES256"],
        "display_values_supported": ["page", "popup"],
        "claim_types_supported": ["normal", "distributed"],
        "claims_supported": ["sub", "iss", "auth_time", "acr", "name",
                             "given_name", "family_name", "nickname", "profile",
                             "picture", "website", "email", "email_verified",
                             "locale", "zoneinfo",
                             "http://example.info/claims/groups"],
        "claims_parameter_supported": True,
        "service_documentation":
            "http://server.example.com/connect/service_documentation.html",
        "ui_locales_supported": ["en-US", "en-GB", "en-CA", "fr-FR", "fr-CA"]
    }

    pcr = ProviderConfigurationResponse().deserialize(json.dumps(resp), "json")
    rk = resp.keys()
    # parameters with default value if missing
    rk.extend(["grant_types_supported", "request_parameter_supported",
               "request_uri_parameter_supported",
               "require_request_uri_registration"])
    rk.sort()
    pk = pcr.keys()
    pk.sort()
    print rk
    print pk
    assert _eq(pk, rk)
Example #7
0
def test_example_response():
    resp = {
        "version": "3.0",
        "issuer": "https://server.example.com",
        "authorization_endpoint":
            "https://server.example.com/connect/authorize",
        "token_endpoint": "https://server.example.com/connect/token",
        "token_endpoint_auth_methods_supported": ["client_secret_basic",
                                                  "private_key_jwt"],
        "token_endpoint_alg_values_supported": ["RS256", "ES256"],
        "userinfo_endpoint": "https://server.example.com/connect/userinfo",
        "check_session_iframe":
            "https://server.example.com/connect/check_session",
        "end_session_endpoint":
            "https://server.example.com/connect/end_session",
        "jwks_uri": "https://server.example.com/jwks.json",
        "registration_endpoint": "https://server.example.com/connect/register",
        "scopes_supported": ["openid", "profile", "email", "address",
                             "phone", "offline_access"],
        "response_types_supported": ["code", "code id_token", "id_token",
                                     "token id_token"],
        "acr_values_supported": ["urn:mace:incommon:iap:silver",
                                 "urn:mace:incommon:iap:bronze"],
        "subject_types_supported": ["public", "pairwise"],
        "userinfo_signing_alg_values_supported": ["RS256", "ES256", "HS256"],
        "userinfo_encryption_alg_values_supported": ["RSA1_5", "A128KW"],
        "userinfo_encryption_enc_values_supported": ["A128CBC+HS256",
                                                     "A128GCM"],
        "id_token_signing_alg_values_supported": ["RS256", "ES256", "HS256"],
        "id_token_encryption_alg_values_supported": ["RSA1_5", "A128KW"],
        "id_token_encryption_enc_values_supported": ["A128CBC+HS256",
                                                     "A128GCM"],
        "request_object_signing_alg_values_supported": ["none", "RS256",
                                                        "ES256"],
        "display_values_supported": ["page", "popup"],
        "claim_types_supported": ["normal", "distributed"],
        "claims_supported": ["sub", "iss", "auth_time", "acr", "name",
                             "given_name", "family_name", "nickname", "profile",
                             "picture", "website", "email", "email_verified",
                             "locale", "zoneinfo",
                             "http://example.info/claims/groups"],
        "claims_parameter_supported": True,
        "service_documentation":
            "http://server.example.com/connect/service_documentation.html",
        "ui_locales_supported": ["en-US", "en-GB", "en-CA", "fr-FR", "fr-CA"]
    }

    pcr = ProviderConfigurationResponse().deserialize(json.dumps(resp), "json")
    rk = resp.keys()
    # parameters with default value if missing
    rk.extend(["grant_types_supported", "request_parameter_supported",
               "request_uri_parameter_supported",
               "require_request_uri_registration"])
    rk.sort()
    pk = pcr.keys()
    pk.sort()
    print rk
    print pk
    assert _eq(pk, rk)
Example #8
0
    def provider_config(self, issuer, keys=True, endpoints=True):
        if issuer.endswith("/"):
            _issuer = issuer[:-1]
        else:
            _issuer = issuer

        url = OIDCONF_PATTERN % _issuer

        pcr = None
        r = self.http_request(url)
        if r.status_code == 200:
            pcr = ProviderConfigurationResponse().from_json(r.text)
        elif r.status_code == 302:
            while r.status_code == 302:
                r = self.http_request(r.headers["location"])
                if r.status_code == 200:
                    pcr = ProviderConfigurationResponse().from_json(r.text)
                    break

        if pcr is None:
            raise Exception("Trying '%s', status %s" % (url, r.status_code))

        if "issuer" in pcr:
            _pcr_issuer = pcr["issuer"]
            if pcr["issuer"].endswith("/"):
                if issuer.endswith("/"):
                    _issuer = issuer
                else:
                    _issuer = issuer + "/"
            else:
                if issuer.endswith("/"):
                    _issuer = issuer[:-1]
                else:
                    _issuer = issuer

            try:
                assert _issuer == _pcr_issuer
            except AssertionError:
                raise Exception("provider info issuer mismatch '%s' != '%s'" % (
                    _issuer, _pcr_issuer))

            self.provider_info[_pcr_issuer] = pcr
        else:
            _pcr_issuer = issuer

        if endpoints:
            for key, val in pcr.items():
                if key.endswith("_endpoint"):
                    setattr(self, key, val)

        if keys:
            self.keyjar.load_keys(pcr, _pcr_issuer)

        return pcr
Example #9
0
    def providerinfo_endpoint(self, environ, start_response, **kwargs):
        logger.info("@providerinfo_endpoint")
        try:
            _response = ProviderConfigurationResponse(
                            issuer=self.baseurl,
                            token_endpoint_auth_types_supported=[
                                                        "client_secret_post",
                                                        "client_secret_basic",
                                                        "client_secret_jwt"],
                            scopes_supported=["openid"],
                            response_types_supported=["code", "token",
                                                      "id_token", "code token",
                                                      "code id_token",
                                                      "token id_token",
                                                      "code token id_token"],
                            user_id_types_supported=["public"],
                            #request_object_algs_supported=["HS256"]
                        )

            if not self.baseurl.endswith("/"):
                self.baseurl += "/"

            #keys = self.keystore.keys_by_owner(owner=".")
            #for cert in self.cert:
            #    _response["x509_url"] = "%s%s" % (self.baseurl, cert)

            if self.jwk:
                _response["jwk_url"] = self.jwk

            #logger.info("endpoints: %s" % self.endpoints)
            for endp in self.endpoints:
                #logger.info("# %s, %s" % (endp, endp.name))
                _response[endp.name] = "%s%s" % (self.baseurl, endp.type)

            #if self.test_mode:
                #print sys.stderr >> "providerinfo_endpoint.handle: %s" %
                # kwargs["handle"]

            logger.info("provider_info_response: %s" % (_response.to_dict(),))

            headers=[("Cache-Control", "no-store"), ("x-ffo", "bar")]
            if "handle" in kwargs:
                (key, timestamp) = kwargs["handle"]
                if key.startswith(STR) and key.endswith(STR):
                    cookie = self.cookie_func(self.cookie_name, key, self.seed,
                                              self.cookie_ttl)
                    headers.append(cookie)

            resp = Response(_response.to_json(), content="application/json",
                            headers=headers)
        except Exception, err:
            message = traceback.format_exception(*sys.exc_info())
            logger.error(message)
            resp = Response(message, content="html/text")
Example #10
0
    def __init__(self, signing_key, configuration_information, authz_state, clients, userinfo, *,
                 id_token_lifetime=3600, extra_scopes=None):
        # type: (jwkest.jwk.Key, Dict[str, Union[str, Sequence[str]]], se_leg_op.authz_state.AuthorizationState,
        #        Mapping[str, Mapping[str, Any]], se_leg_op.userinfo.Userinfo, int) -> None
        """
        Creates a new provider instance.
        :param configuration_information: see
            <a href="https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata">
            "OpenID Connect Discovery 1.0", Section 3</a>
        :param clients: see <a href="https://openid.net/specs/openid-connect-registration-1_0.html#ClientMetadata">
            "OpenID Connect Dynamic Client Registration 1.0", Section 2</a>
        :param userinfo: read-only interface for user info
        :param id_token_lifetime: how long the signed ID Tokens should be valid (in seconds), defaults to 1 hour
        """
        self.signing_key = signing_key
        self.configuration_information = ProviderConfigurationResponse(**configuration_information)
        if 'subject_types_supported' not in configuration_information:
            self.configuration_information['subject_types_supported'] = ['pairwise']
        if 'id_token_signing_alg_values_supported' not in configuration_information:
            self.configuration_information['id_token_signing_alg_values_supported'] = ['RS256']
        if 'scopes_supported' not in configuration_information:
            self.configuration_information['scopes_supported'] = ['openid']
        if 'response_types_supported' not in configuration_information:
            self.configuration_information['response_types_supported'] = ['code', 'id_token', 'token id_token']

        self.extra_scopes = {} if extra_scopes is None else extra_scopes
        _scopes = self.configuration_information['scopes_supported']
        _scopes.extend(self.extra_scopes.keys())
        self.configuration_information['scopes_supported'] = list(set(_scopes))

        self.configuration_information.verify()

        self.authz_state = authz_state
        self.clients = clients
        self.userinfo = userinfo
        self.id_token_lifetime = id_token_lifetime

        self.authentication_request_validators = []  # type: List[Callable[[oic.oic.message.AuthorizationRequest], Boolean]]
        self.authentication_request_validators.append(authorization_request_verify)
        self.authentication_request_validators.append(
            functools.partial(client_id_is_known, self))
        self.authentication_request_validators.append(
            functools.partial(redirect_uri_is_in_registered_redirect_uris, self))
        self.authentication_request_validators.append(
            functools.partial(response_type_is_in_registered_response_types, self))
        self.authentication_request_validators.append(userinfo_claims_only_specified_when_access_token_is_issued)
        self.authentication_request_validators.append(functools.partial(requested_scope_is_supported, self))

        self.registration_request_validators = []  # type: List[Callable[[oic.oic.message.RegistrationRequest], Boolean]]
        self.registration_request_validators.append(registration_request_verify)
        self.registration_request_validators.append(
            functools.partial(client_preferences_match_provider_capabilities, self))
Example #11
0
    def test_deserialize(self):
        resp = {
            "authorization_endpoint":
            "https://server.example.com/connect/authorize",
            "issuer":
            "https://server.example.com",
            "token_endpoint":
            "https://server.example.com/connect/token",
            "token_endpoint_auth_methods_supported": [
                "client_secret_basic",
                "private_key_jwt",
            ],
            "userinfo_endpoint":
            "https://server.example.com/connect/user",
            "check_id_endpoint":
            "https://server.example.com/connect/check_id",
            "refresh_session_endpoint":
            "https://server.example.com/connect/refresh_session",
            "end_session_endpoint":
            "https://server.example.com/connect/end_session",
            "jwk_url":
            "https://server.example.com/jwk.json",
            "registration_endpoint":
            "https://server.example.com/connect/register",
            "scopes_supported":
            ["openid", "profile", "email", "address", "phone"],
            "response_types_supported":
            ["code", "code id_token", "token id_token"],
            "acrs_supported":
            ["1", "2", "http://id.incommon.org/assurance/bronze"],
            "user_id_types_supported": ["public", "pairwise"],
            "userinfo_algs_supported": [
                "HS256",
                "RS256",
                "A128CBC",
                "A128KW",
                "RSA1_5",
            ],
            "id_token_algs_supported": [
                "HS256",
                "RS256",
                "A128CBC",
                "A128KW",
                "RSA1_5",
            ],
            "request_object_algs_supported": [
                "HS256",
                "RS256",
                "A128CBC",
                "A128KW",
                "RSA1_5",
            ],
        }

        pcr = ProviderConfigurationResponse().deserialize(
            json.dumps(resp), "json")

        assert _eq(pcr["user_id_types_supported"], ["public", "pairwise"])
        assert _eq(pcr["acrs_supported"],
                   ["1", "2", "http://id.incommon.org/assurance/bronze"])
Example #12
0
def _create_client(provider_metadata, client_metadata, verify_ssl=True):
    """
    Create a pyoidc client instance.
    :param provider_metadata: provider configuration information
    :type provider_metadata: Mapping[str, Union[str, Sequence[str]]]
    :param client_metadata: client metadata
    :type client_metadata: Mapping[str, Union[str, Sequence[str]]]
    :return: client instance to use for communicating with the configured provider
    :rtype: oic.oic.Client
    """
    client = oic.Client(client_authn_method=CLIENT_AUTHN_METHOD,
                        verify_ssl=verify_ssl)

    # Provider configuration information
    if "authorization_endpoint" in provider_metadata:
        # no dynamic discovery necessary
        client.handle_provider_config(
            ProviderConfigurationResponse(**provider_metadata),
            provider_metadata["issuer"])
    else:
        # do dynamic discovery
        client.provider_config(provider_metadata["issuer"])

    # Client information
    if "client_id" in client_metadata:
        # static client info provided
        client.store_registration_info(RegistrationRequest(**client_metadata))
    else:
        # do dynamic registration
        client.register(client.provider_info['registration_endpoint'],
                        **client_metadata)

    client.subject_type = (client.registration_response.get("subject_type") or
                           client.provider_info["subject_types_supported"][0])
    return client
Example #13
0
    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,
                              settings=provider_configuration.client_settings)
        # Token Introspection is implemented under extension sub-package of
        # the client in pyoidc.
        self._client_extension = ClientExtension(
            client_authn_method=CLIENT_AUTHN_METHOD,
            settings=provider_configuration.client_settings)
        # Client Credentials Flow is implemented under oauth2 sub-package of
        # the client in pyoidc.
        self._oauth2_client = Oauth2Client(
            client_authn_method=CLIENT_AUTHN_METHOD,
            message_factory=CCMessageFactory,
            settings=self._provider_configuration.client_settings)

        provider_metadata = provider_configuration.ensure_provider_metadata(
            self._client)
        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(
            )
            client_metadata.update(redirect_uris=list(redirect_uri))
            self._store_registration_info(client_metadata)

        self._redirect_uri = redirect_uri
Example #14
0
def setup_conv():
    entity = Client(client_authn_method=CLIENT_AUTHN_METHOD, verify_ssl=False)
    entity.provider_info = ProviderConfigurationResponse(
        authorization_endpoint="https://example.com", )

    cls_factories = {'': oper.factory}
    func_factory = func.factory

    flow_state = FlowState('flows',
                           profile_handler=ProfileHandler,
                           cls_factories=cls_factories,
                           func_factory=func_factory,
                           display_order=OP_ORDER)
    iss = 'https://example.org'
    tag = 'foobar'
    session_handler = SessionHandler(iss, tag, flows=flow_state,
                                     tool_conf={})  # , rest=rest, **webenv)
    session_handler.iss = iss
    session_handler.tag = tag

    info = WebIh(session=session_handler, profile_handler=ProfileHandler)

    conv = Conversation([], entity, factory, callback_uris=[])
    conv.events = Events()
    conv.tool_config = {}
    return {'conv': conv, 'io': info}
Example #15
0
    def init_relationship(self, provider_url):
        if not self.provider_info:
            opc = ProviderConfigurationResponse()
            try:
                pcr = self.provider_config(provider_url,
                                           serv_pattern=UMACONF_PATTERN)
            except Exception, err:
                raise
            else:
                opc.update(pcr)

            try:
                pcr = self.provider_config(provider_url,
                                           serv_pattern=UMACONF_PATTERN)
            except Exception, err:
                raise
Example #16
0
    def test_full_flow(self, context, frontend_with_extra_scopes):
        redirect_uri = "https://client.example.com/redirect"
        response_type = "code id_token token"
        mock_callback = Mock()
        frontend_with_extra_scopes.auth_req_callback_func = mock_callback
        # discovery
        http_response = frontend_with_extra_scopes.provider_config(context)
        provider_config = ProviderConfigurationResponse().deserialize(http_response.message, "json")

        # client registration
        registration_request = RegistrationRequest(redirect_uris=[redirect_uri], response_types=[response_type])
        context.request = registration_request.to_dict()
        http_response = frontend_with_extra_scopes.client_registration(context)
        registration_response = RegistrationResponse().deserialize(http_response.message, "json")

        # authentication request
        authn_req = AuthorizationRequest(
            redirect_uri=redirect_uri,
            client_id=registration_response["client_id"],
            response_type=response_type,
            scope="openid email eduperson",
            state="state",
            nonce="nonce",
        )
        context.request = dict(parse_qsl(authn_req.to_urlencoded()))
        frontend_with_extra_scopes.handle_authn_request(context)
        assert mock_callback.call_count == 1

        # fake authentication response from backend
        internal_response = self.setup_for_authn_response(
            context, frontend_with_extra_scopes, authn_req
        )
        http_response = frontend_with_extra_scopes.handle_authn_response(
            context, internal_response
        )
        authn_resp = AuthorizationResponse().deserialize(urlparse(http_response.message).fragment, "urlencoded")
        assert "code" in authn_resp
        assert "access_token" in authn_resp
        assert "id_token" in authn_resp

        # token request
        context.request = AccessTokenRequest(redirect_uri=authn_req["redirect_uri"], code=authn_resp["code"]).to_dict()
        credentials = "{}:{}".format(registration_response["client_id"], registration_response["client_secret"])
        basic_auth = urlsafe_b64encode(credentials.encode("utf-8")).decode("utf-8")
        context.request_authorization = "Basic {}".format(basic_auth)

        http_response = frontend_with_extra_scopes.token_endpoint(context)
        parsed = AccessTokenResponse().deserialize(http_response.message, "json")
        assert "access_token" in parsed
        assert "id_token" in parsed

        # userinfo request
        context.request = {}
        context.request_authorization = "Bearer {}".format(parsed["access_token"])
        http_response = frontend_with_extra_scopes.userinfo_endpoint(context)
        parsed = OpenIDSchema().deserialize(http_response.message, "json")
        assert "email" in parsed
        assert "eduperson_principal_name" in parsed
        assert "eduperson_scoped_affiliation" in parsed
Example #17
0
 def run(self):
     if self.dynamic:
         self.catch_exception_and_error(self.conv.entity.provider_config,
                                        **self.op_args)
     else:
         self.conv.events.store(EV_NOOP, "Dynamic discovery")
         self.conv.entity.provider_info = ProviderConfigurationResponse(
             **self.conv.entity_config["provider_info"])
Example #18
0
    def test_complete_auth_token_idtoken_no_alg_config(self):
        _state = "state0"
        self.consumer.consumer_config["response_type"] = ["id_token", "token"]
        self.consumer.provider_info = ProviderConfigurationResponse(
            issuer="https://example.com")  # abs min
        self.consumer.authz_req = {}  # Store AuthzReq with state as key

        args = {
            "client_id": self.consumer.client_id,
            "response_type": self.consumer.consumer_config["response_type"],
            "scope": ["openid"],
            "nonce": "nonce",
        }
        token = IdToken(
            iss="https://example.com",
            aud="client_1",
            sub="some_sub",
            exp=1565348600,
            iat=1565348300,
            nonce="nonce",
        )
        location = (
            "https://example.com/cb?state=state0&access_token=token&token_type=bearer&"
            "scope=openid&id_token={}".format(
                token.to_jwt(key=[SYMKey(key="hemlig")], algorithm="HS256")))
        with responses.RequestsMock() as rsps:
            rsps.add(
                responses.GET,
                "https://example.com/authorization",
                status=302,
                headers={"location": location},
            )
            result = self.consumer.do_authorization_request(state=_state,
                                                            request_args=args)
            query = parse_qs(urlparse(result.request.url).query)
            assert query["client_id"] == ["client_1"]
            assert query["scope"] == ["openid"]
            assert query["response_type"] == ["id_token token"]
            assert query["state"] == ["state0"]
            assert query["nonce"] == ["nonce"]
            assert query["redirect_uri"] == ["https://example.com/cb"]

        parsed = urlparse(result.headers["location"])

        with freeze_time("2019-08-09 11:00:00"):
            part = self.consumer.parse_authz(query=parsed.query,
                                             algs={"sign": "HS256"})
        assert isinstance(part, tuple)
        auth = part[0]
        atr = part[1]
        idt = part[2]

        assert auth is None
        assert isinstance(atr, AccessTokenResponse)
        assert _eq(
            atr.keys(),
            ["access_token", "id_token", "token_type", "state", "scope"])
        assert isinstance(idt, IdToken)
Example #19
0
    def _provider_config(self, context):
        """
        Construct the provider configuration information (served at /.well-known/openid-configuration).
        :type context: satosa.context.Context
        :rtype: oic.utils.http_util.Response

        :param context: the current context
        :return: HTTP response to the client
        """
        http_resp = self.provider.providerinfo_endpoint()
        if not isinstance(http_resp, Response):
            return http_resp
        provider_config = ProviderConfigurationResponse().deserialize(http_resp.message, "json")
        del provider_config["token_endpoint_auth_methods_supported"]
        del provider_config["require_request_uri_registration"]

        http_resp.message = provider_config.to_json()
        return http_resp
Example #20
0
    def test_provider_configuration_endpoint(self):
        expected_capabilities = {
            "response_types_supported": ["id_token"],
            "id_token_signing_alg_values_supported": ["RS256"],
            "response_modes_supported": ["fragment", "query"],
            "subject_types_supported": ["public", "pairwise"],
            "grant_types_supported": ["implicit"],
            "claim_types_supported": ["normal"],
            "claims_parameter_supported": True,
            "request_parameter_supported": False,
            "request_uri_parameter_supported": False,
        }

        http_response = self.instance._provider_config(Context())
        provider_config = ProviderConfigurationResponse().deserialize(http_response.message, "json")
        assert all(
                item in provider_config.to_dict().items() for item in expected_capabilities.items())
        assert provider_config["authorization_endpoint"] == "{}/foo_backend/authorization".format(self.ISSUER)
Example #21
0
def prepare_client():
    # http://pyoidc.readthedocs.io/en/latest/examples/rp.html


    # Instantiate a client
    client = Client(client_authn_method=CLIENT_AUTHN_METHOD)


    # Register the OP
    # endpoints are now loaded from a json file rather than defined here
    # DEV endpoints
    # issuer = "https://unity.eudat-aai.fz-juelich.de:443"
    # authorization_endpoint = "https://unity.eudat-aai.fz-juelich.de:443/oauth2-as/oauth2-authz"
    # token_endpoint = "https://unity.eudat-aai.fz-juelich.de:443/oauth2/token"
    # userinfo_endpoint = "https://unity.eudat-aai.fz-juelich.de:443/oauth2/userinfo"
    # PROD endpoints
    # issuer = "https://b2access.eudat.eu:443"
    # authorization_endpoint = "https://b2access.eudat.eu:443/oauth2-as/oauth2-authz"
    # token_endpoint = "https://b2access.eudat.eu:443/oauth2/token"
    # userinfo_endpoint = "https://b2access.eudat.eu:443/oauth2/userinfo"
    try:
        dir = os.path.dirname(__file__)
        provider_endpoints = json.load(open(dir + '/provider_endpoints.json'))
        issuer = provider_endpoints['issuer']
        authorization_endpoint = provider_endpoints['authorization_endpoint']
        token_endpoint = provider_endpoints['token_endpoint']
        userinfo_endpoint = provider_endpoints['userinfo_endpoint']
    except:
        print "Error when reading provider_endpoints.json"
        stdlogger.error("Error when reading provider_endpoints.json")
        issuer = "error"
        authorization_endpoint = "error"
        token_endpoint = "error"
        userinfo_endpoint = "error"
    op_info = ProviderConfigurationResponse(issuer=issuer, authorization_endpoint=authorization_endpoint, token_endpoint=token_endpoint, userinfo_endpoint=userinfo_endpoint)
    client.provider_info = op_info


    # Set our credentials (that we got from manually registering to B2Access), as well as the redirect URI
    try:
        dir = os.path.dirname(__file__)
        client_credentials = json.load(open(dir + '/client_credentials.json'))
        id = client_credentials['client_id']
        secret = client_credentials['client_secret']
        uri = client_credentials['client_redirect_uri']
    except:
        print "Error when reading client_credential.json"
        stdlogger.error("Error when reading client_credential.json")
        id = "error"
        secret = "error"
        uri = "error"
    # /!\ Added the redirect URI here, else it's not defined later (in args ={[...] client.registration_response["redirect_uris"][0])
    uris = [uri]
    info = {"client_id": id, "client_secret": secret, "redirect_uris": uris}
    client_reg = RegistrationResponse(**info)
    client.store_registration_info(client_reg)
    return client
Example #22
0
    def _provider_config(self, context):
        """
        Construct the provider configuration information (served at /.well-known/openid-configuration).
        :type context: satosa.context.Context
        :rtype: oic.utils.http_util.Response

        :param context: the current context
        :return: HTTP response to the client
        """
        http_resp = self.provider.providerinfo_endpoint()
        if not isinstance(http_resp, Response):
            return http_resp
        provider_config = ProviderConfigurationResponse().deserialize(
            http_resp.message, "json")
        del provider_config["token_endpoint_auth_methods_supported"]
        del provider_config["require_request_uri_registration"]

        http_resp.message = provider_config.to_json()
        return http_resp
Example #23
0
    def test_register_endpoints_dynamic_client_registration_is_configurable(
            self, frontend_config, client_registration_enabled):
        frontend_config["provider"]["client_registration_supported"] = client_registration_enabled
        frontend = self.create_frontend(frontend_config)

        urls = frontend.register_endpoints(["test"])
        assert (("^{}/{}".format(frontend.name, RegistrationEndpoint.url),
                 frontend.client_registration) in urls) == client_registration_enabled
        provider_info = ProviderConfigurationResponse().deserialize(frontend.provider_config(None).message, "json")
        assert ("registration_endpoint" in provider_info) == client_registration_enabled
Example #24
0
 def _build_oidc_client(self):
     client = Client(client_authn_method=CLIENT_AUTHN_METHOD)
     provider_config = ProviderConfigurationResponse(
         **self.settings["oidc"]["provider"]["configuration"])
     client.handle_provider_config(provider_config,
                                   provider_config["issuer"])
     client.store_registration_info(
         RegistrationResponse(
             **self.settings["oidc"]["provider"]["registration"]))
     return client
Example #25
0
def create_oidc_client(issuer=None, registration_info=None):
    if "oidc" not in g:
        g.oidc = Client(client_authn_method=CLIENT_AUTHN_METHOD)
        config = get(f"{issuer}/.well-known/openid-configuration", headers={"Content-type": "application/json"}).json()
        provider_config = ProviderConfigurationResponse(**config)
        g.oidc.handle_provider_config(provider_config, issuer)
        g.oidc.store_registration_info(
            RegistrationResponse(**registration_info)
        )
        g.oidc.redirect_uris.append(f"{g.oidc.registration_response['redirect_uris'][0]}/callback")
    return g.oidc
Example #26
0
    def test_token_endpoint_is_not_required_for_implicit_flow_only(self):
        provider_config = {
            "issuer": "https://server.example.com",
            "authorization_endpoint": "https://server.example.com/connect/authorize",
            "jwks_uri": "https://server.example.com/jwks.json",
            "response_types_supported": ["id_token", "token id_token"],
            "subject_types_supported": ["public", "pairwise"],
            "id_token_signing_alg_values_supported": ["RS256", "ES256", "HS256"],
        }

        # should not raise an exception
        assert ProviderConfigurationResponse(**provider_config).verify()
Example #27
0
    def test_register_endpoints_token_and_userinfo_endpoint_is_not_published_if_only_implicit_flow(
            self, frontend_config, context):
        frontend_config["provider"]["response_types_supported"] = ["id_token", "id_token token"]
        frontend = self.create_frontend(frontend_config)

        urls = frontend.register_endpoints(["test"])
        assert ("^{}/{}".format("test", TokenEndpoint.url), frontend.token_endpoint) not in urls
        assert ("^{}/{}".format("test", UserinfoEndpoint.url), frontend.userinfo_endpoint) not in urls

        http_response = frontend.provider_config(context)
        provider_config = ProviderConfigurationResponse().deserialize(http_response.message, "json")
        assert "token_endpoint" not in provider_config
Example #28
0
    def test_token_endpoint_is_required_for_other_than_implicit_flow_only(self):
        provider_config = {
            "issuer": "https://server.example.com",
            "authorization_endpoint": "https://server.example.com/connect/authorize",
            "jwks_uri": "https://server.example.com/jwks.json",
            "response_types_supported": ["code", "id_token"],
            "subject_types_supported": ["public", "pairwise"],
            "id_token_signing_alg_values_supported": ["RS256", "ES256", "HS256"],
        }

        with pytest.raises(MissingRequiredAttribute):
            ProviderConfigurationResponse(**provider_config).verify()
Example #29
0
    def test_complete_auth_token_idtoken_none_cipher_token(self):
        _state = "state0"
        self.consumer.consumer_config["response_type"] = ["token"]
        self.consumer.registration_response = RegistrationResponse(
            id_token_signed_response_alg="none")
        self.consumer.provider_info = ProviderConfigurationResponse(
            issuer="https://example.com")  # abs min
        self.consumer.authz_req = {}  # Store AuthzReq with state as key
        self.consumer.sdb[_state] = {"redirect_uris": []}

        args = {
            "client_id": self.consumer.client_id,
            "response_type": self.consumer.consumer_config["response_type"],
            "scope": ["openid"],
            "nonce": "nonce",
        }
        token = IdToken(
            iss="https://example.com",
            aud="client_1",
            sub="some_sub",
            exp=1565348600,
            iat=1565348300,
            nonce="nonce",
        )
        # Downgrade the algorithm to `none`
        location = (
            "https://example.com/cb?state=state0&access_token=token&token_type=bearer&"
            "scope=openid&id_token={}".format(
                token.to_jwt(key=KC_RSA.keys(), algorithm="none")))
        with responses.RequestsMock() as rsps:
            rsps.add(
                responses.GET,
                "https://example.com/authorization",
                status=302,
                headers={"location": location},
            )
            result = self.consumer.do_authorization_request(state=_state,
                                                            request_args=args)
            query = parse_qs(urlparse(result.request.url).query)
            assert query["client_id"] == ["client_1"]
            assert query["scope"] == ["openid"]
            assert query["response_type"] == ["token"]
            assert query["state"] == ["state0"]
            assert query["nonce"] == ["nonce"]
            assert query["redirect_uri"] == ["https://example.com/cb"]

        parsed = urlparse(result.headers["location"])

        with freeze_time("2019-08-09 11:00:00"):
            with pytest.raises(WrongSigningAlgorithm):
                self.consumer.parse_authz(query=parsed.query)
Example #30
0
File: client.py Project: rohe/pyuma
    def init_relationship(self, provider_url):
        if not self.provider_info:
            opc = ProviderConfigurationResponse()
            try:
                pcr = self.provider_config(provider_url,
                                           serv_pattern=UMACONF_PATTERN)
            except Exception as err:
                raise
            else:
                opc.update(pcr)

            if 'oidc_provider' in self.conf:
                try:
                    pcr = self.oidc_client.provider_config(provider_url)
                except Exception as err:
                    raise
                else:
                    opc.update(pcr)

            self.provider_info = opc

        if not self.client_secret:
            self.register(
                self.provider_info["dynamic_client_endpoint"])
Example #31
0
    def test_required_parameters(self, required_param):
        provider_config = {
            "issuer": "https://server.example.com",
            "authorization_endpoint":
                "https://server.example.com/connect/authorize",
            "jwks_uri": "https://server.example.com/jwks.json",
            "response_types_supported": ["code", "code id_token", "id_token",
                                         "token id_token"],
            "subject_types_supported": ["public", "pairwise"],
            "id_token_signing_alg_values_supported": ["RS256", "ES256",
                                                      "HS256"],
        }

        del provider_config[required_param]
        with pytest.raises(MissingRequiredAttribute):
            ProviderConfigurationResponse(**provider_config).verify()
Example #32
0
    def __init__(self,
                 flask_app,
                 client_registration_info=None,
                 issuer=None,
                 provider_configuration_info=None,
                 userinfo_endpoint_method='POST',
                 extra_request_args=None):
        self.app = flask_app
        self.userinfo_endpoint_method = userinfo_endpoint_method
        self.extra_request_args = extra_request_args or {}

        self.client = Client(client_authn_method=CLIENT_AUTHN_METHOD)

        # Raise exception if oic auth will fail based on lack of data.
        if not issuer and not provider_configuration_info:
            raise ValueError(
                'Either \'issuer\' (for dynamic discovery) or provider_configuration_info'
                ' for static configuration must be specified.')
        # If only issuer provided assume discovery and initalize anyway.
        if issuer and not provider_configuration_info:
            self.client.provider_config(issuer)
        else:
            # Otherwise assume non-discovery for oidc
            self.client.handle_provider_config(
                ProviderConfigurationResponse(**provider_configuration_info),
                provider_configuration_info['issuer'])

        self.client_registration_info = client_registration_info or {}

        # setup redirect_uri as a flask route
        self.app.add_url_rule('/redirect_uri', 'redirect_uri',
                              self._handle_authentication_response)

        # dynamically add the Flask redirect uri to the client info
        with self.app.app_context():
            self.client_registration_info['redirect_uris'] \
                = url_for('redirect_uri')

        # if non-discovery client add the provided info from the constructor
        if client_registration_info and 'client_id' in client_registration_info:
            # static client info provided
            self.client.store_registration_info(
                RegistrationRequest(**client_registration_info))

        self.logout_view = None
        self._error_view = None
Example #33
0
    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
Example #34
0
    def parse_args(self):
        OAuth2.parse_args(self)

        if self.args.external_server:
            self.environ["keyprovider"] = None

        _keyjar = self.client.keyjar
        pcr = ProviderConfigurationResponse()
        n = 0
        for param in URL_TYPES:
            if param in self.pinfo:
                n += 1
                pcr[param] = self.pinfo[param]

        if n:
            if _keyjar is None:
                _keyjar = self.client.keyjar = KeyJar()
            _keyjar.load_keys(pcr, self.pinfo["issuer"])
Example #35
0
    def setup_consumer(self, session_db_factory):
        client_id = "client_1"
        client_config = {
            "client_id": client_id,
            "client_authn_method": CLIENT_AUTHN_METHOD,
        }

        self.consumer = Consumer(DictSessionBackend(), CONFIG, client_config,
                                 SERVER_INFO)
        self.consumer.behaviour = {
            "request_object_signing_alg": DEF_SIGN_ALG["openid_request_object"]
        }
        self.consumer.keyjar = CLIKEYS
        self.consumer.redirect_uris = ["https://example.com/cb"]
        self.consumer.authorization_endpoint = "https://example.com/authorization"
        self.consumer.token_endpoint = "https://example.com/token"
        self.consumer.userinfo_endpoint = "https://example.com/userinfo"  # type: ignore
        self.consumer.client_secret = "hemlig"
        self.consumer.secret_type = "basic"
        self.consumer.provider_info = ProviderConfigurationResponse(
            issuer="https://example.com")  # abs min
Example #36
0
    def create_client(self):
        """Create the OpenIDConnect client from the data stored in the contest
        object, and store some information in this handler object.
        """
        oic_info = json.loads(self.contest.openidconnect_info)
        self.redirect_uri = (
            self.request.protocol + "://" + self.request.host
            + self.request.path)
        self.op_info = oic_info["op_info"]
        self.client_info = oic_info["client_info"]
        self.client_info["redirect_uris"] = [self.redirect_uri]
        self.jwks = oic_info["jwks"]

        keyjar = KeyJar()
        keyjar.import_jwks(self.jwks, self.op_info["issuer"])

        self.client = Client(
            client_authn_method=CLIENT_AUTHN_METHOD, keyjar=keyjar)
        self.client.provider_info = \
            ProviderConfigurationResponse(**self.op_info)
        self.client.store_registration_info(
            RegistrationResponse(**self.client_info))
Example #37
0
    def __init__(self,
                 flask_app,
                 client_registration_info=None,
                 issuer=None,
                 provider_configuration_info=None,
                 userinfo_endpoint_method='POST',
                 extra_request_args=None):
        self.app = flask_app
        self.userinfo_endpoint_method = userinfo_endpoint_method
        self.extra_request_args = extra_request_args or {}

        self.client = Client(client_authn_method=CLIENT_AUTHN_METHOD)
        if not issuer and not provider_configuration_info:
            raise ValueError(
                'Either \'issuer\' (for dynamic discovery) or \'provider_configuration_info\' (for static configuration must be specified.'
            )
        if issuer and not provider_configuration_info:
            self.client.provider_config(issuer)
        else:
            self.client.handle_provider_config(
                ProviderConfigurationResponse(**provider_configuration_info),
                provider_configuration_info['issuer'])

        self.client_registration_info = client_registration_info or {}

        # setup redirect_uri
        self.app.add_url_rule('/redirect_uri', 'redirect_uri',
                              self._handle_authentication_response)
        with self.app.app_context():
            self.client_registration_info['redirect_uris'] = url_for(
                'redirect_uri')

        if client_registration_info and 'client_id' in client_registration_info:
            # static client info provided
            self.client.store_registration_info(
                RegistrationRequest(**client_registration_info))

        self.logout_view = None
        self._error_view = None
Example #38
0
def create_openid_client(oidc_provider_config, client_id, client_secret):
    """
    Build an OIDC client using the oidc provider configuration
    """
    # build our OpenID client
    openid_client = Client(client_authn_method=CLIENT_AUTHN_METHOD,
                           client_id=client_id)

    # save the client information to the OIDC client
    client_registration_info = RegistrationResponse(
        **{
            "client_id": client_id,
            "client_secret": client_secret
        })
    openid_client.store_registration_info(client_registration_info)

    # save the provider config to the OIDC client
    provider_configuration = ProviderConfigurationResponse(
        **oidc_provider_config)
    openid_client.handle_provider_config(provider_configuration,
                                         provider_configuration['issuer'],
                                         True, True)

    return openid_client
Example #39
0
    def init_relationship(self, provider_url):
        if not self.provider_info:
            opc = ProviderConfigurationResponse()
            try:
                pcr = self.provider_config(provider_url,
                                           serv_pattern=UMACONF_PATTERN)
            except Exception as err:
                raise
            else:
                opc.update(pcr)

            if 'oidc_provider' in self.conf:
                try:
                    pcr = self.oidc_client.provider_config(provider_url)
                except Exception as err:
                    raise
                else:
                    opc.update(pcr)

            self.provider_info = opc

        if not self.client_secret:
            self.register(self.provider_info["dynamic_client_endpoint"])
Example #40
0
    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
Example #41
0
    def providerinfo_endpoint(self, handle="", **kwargs):
        _log_debug = logger.debug
        _log_info = logger.info

        _log_info("@providerinfo_endpoint")
        try:
            _response = ProviderConfigurationResponse(
                issuer=self.baseurl,
                token_endpoint_auth_methods_supported=[
                    "client_secret_post", "client_secret_basic",
                    "client_secret_jwt", "private_key_jwt"],
                scopes_supported=["openid"],
                response_types_supported=["code", "token", "id_token",
                                          "code token", "code id_token",
                                          "token id_token",
                                          "code token id_token"],
                subject_types_supported=["public", "pairwise"],
                grant_types_supported=[
                    "authorization_code", "implicit",
                    "urn:ietf:params:oauth:grant-type:jwt-bearer"],
                claim_types_supported=["normal", "aggregated", "distributed"],
                claims_supported=SCOPE2CLAIMS.keys(),
                claims_parameter_supported="true",
                request_parameter_supported="true",
                request_uri_parameter_supported="true",
                #request_object_algs_supported=["HS256"]
            )

            sign_algs = jws.SIGNER_ALGS.keys()

            for typ in ["userinfo", "id_token", "request_object",
                        "token_endpoint_auth"]:
                _response["%s_signing_alg_values_supported" % typ] = sign_algs

            algs = jwe.SUPPORTED["alg"]
            for typ in ["userinfo", "id_token", "request_object"]:
                _response["%s_encryption_alg_values_supported" % typ] = algs

            encs = jwe.SUPPORTED["enc"]
            for typ in ["userinfo", "id_token", "request_object"]:
                _response["%s_encryption_enc_values_supported" % typ] = encs

            if not self.baseurl.endswith("/"):
                self.baseurl += "/"

            #keys = self.keyjar.keys_by_owner(owner=".")
            if self.jwks_uri:
                _response["jwks_uri"] = self.jwks_uri

            #_log_info("endpoints: %s" % self.endpoints)
            for endp in self.endpoints:
                #_log_info("# %s, %s" % (endp, endp.name))
                _response[endp.name] = "%s%s" % (self.baseurl, endp.etype)

            _log_info("provider_info_response: %s" % (_response.to_dict(),))

            headers = [("Cache-Control", "no-store"), ("x-ffo", "bar")]
            if handle:
                (key, timestamp) = handle
                if key.startswith(STR) and key.endswith(STR):
                    cookie = self.cookie_func(key, self.cookie_name, "pinfo",
                                              self.sso_ttl)
                    headers.append(cookie)

            resp = Response(_response.to_json(), content="application/json",
                            headers=headers)
        except Exception, err:
            message = traceback.format_exception(*sys.exc_info())
            logger.error(message)
            resp = Response(message, content="html/text")
Example #42
0
    try:
        OAS.cookie_name = config.COOKIENAME
    except AttributeError:
        pass

    OAS.cookie_func = http_util.cookie

    #print URLS
    if args.debug:
        OAS.debug = True

    if args.authn_as:
        OAS.authn_as = args.authn_as

    if args.provider_conf:
        prc = ProviderConfigurationResponse().from_json(open(args.provider_conf).read())
        endpoints = []
        for key in prc.keys():
            if key.endswith("_endpoint"):
                endpoints.append(key)
    else:
        endpoints = ENDPOINTS

    add_endpoints(endpoints)
    OAS.endpoints = endpoints

    if args.port == 80:
        OAS.baseurl = config.baseurl
    else:
        if config.baseurl.endswith("/"):
            config.baseurl = config.baseurl[:-1]