コード例 #1
0
ファイル: test_oic.py プロジェクト: zack53/pyoidc
    def test_parse_registration_request(self):
        regreq = RegistrationRequest(
            contacts=["*****@*****.**"],
            redirect_uris=["http://example.org/jqauthz"],
            application_name="pacubar",
            client_id=CLIENT_ID,
            operation="register",
            application_type="web")

        request = self.srv.parse_registration_request(
            data=regreq.to_urlencoded())
        assert isinstance(request, RegistrationRequest)
        assert _eq(request.keys(), [
            'redirect_uris', 'contacts', 'client_id', 'application_name',
            'operation', 'application_type', 'response_types'
        ])
        assert request["application_name"] == "pacubar"
        assert request["operation"] == "register"
コード例 #2
0
    def test_registration_endpoint(self):
        req = RegistrationRequest()

        req["application_type"] = "web"
        req["client_name"] = "My super service"
        req["redirect_uris"] = ["http://example.com/authz"]
        req["contacts"] = ["*****@*****.**"]
        req["response_types"] = ["code"]

        resp = self.provider.registration_endpoint(request=req.to_json())

        regresp = RegistrationResponse().deserialize(resp.message, "json")
        assert _eq(regresp.keys(), [
            'redirect_uris', 'contacts', 'application_type', 'client_name',
            'registration_client_uri', 'client_secret_expires_at',
            'registration_access_token', 'client_id', 'client_secret',
            'client_id_issued_at', 'response_types'
        ])
コード例 #3
0
    def test_registered_redirect_uri_faulty_with_query_component(self, uri):
        rr = RegistrationRequest(
            operation="register",
            redirect_uris=["http://example.org/cb?foo=bar"],
            response_types=["code"])

        registration_req = rr.to_json()
        resp = self.provider.registration_endpoint(request=registration_req)
        regresp = RegistrationResponse().from_json(resp.message)
        cid = regresp["client_id"]

        areq = AuthorizationRequest(redirect_uri=uri,
                                    client_id=cid,
                                    scope="openid",
                                    response_type="code")

        with pytest.raises(RedirectURIError):
            self.provider._verify_redirect_uri(areq)
コード例 #4
0
ファイル: test_oic_provider.py プロジェクト: wxy148616/pyoidc
    def test_verify_sector_identifier_ru_missing_in_si(self):
        """Redirect_uris is not present in the sector_identifier_uri content."""
        rr = RegistrationRequest(operation="register",
                                 sector_identifier_uri="https://example.com",
                                 redirect_uris=["http://example.com/missing"])
        with responses.RequestsMock() as rsps, LogCapture(
                level=logging.DEBUG) as logcap:
            rsps.add(rsps.GET,
                     "https://example.com",
                     body=json.dumps(["http://example.com/present"]))
            with pytest.raises(
                    InvalidSectorIdentifier,
                    message="redirect uri missing from sector_identifiers"):
                self.provider._verify_sector_identifier(rr)

        assert len(logcap.records) == 2
        assert logcap.records[0].msg == "sector_identifier_uri => %s"
        assert logcap.records[0].args == ('["http://example.com/present"]', )
        assert logcap.records[1].msg == "redirect_uris: %s"
        assert logcap.records[1].args == (["http://example.com/missing"], )
コード例 #5
0
    def registration_endpoint(self, request, authn=None, **kwargs):
        logger.debug("@registration_endpoint: <<%s>>" % sanitize(request))

        try:
            request = ClientMetadataStatement().deserialize(request, "json")
        except ValueError:
            request = ClientMetadataStatement().deserialize(request)

        logger.info("registration_request:%s" % sanitize(request.to_dict()))

        request_args = self.get_metadata_statement(request)
        request = RegistrationRequest(**request_args)

        result = self.client_registration_setup(request)
        if isinstance(result, Response):
            return result

        return Created(result.to_json(),
                       content="application/json",
                       headers=[("Cache-Control", "no-store")])
コード例 #6
0
    def init_app(self, app):
        self._app = app

        if not app.extensions:
            app.extensions = {}

        app.extensions['oidc_client'] = self

        config = app.config.get('OIDC_CLIENT', {})

        client = Client(client_authn_method=CLIENT_AUTHN_METHOD)
        client.provider_config(config['issuer'])

        config['redirect_uris'] = [self._init_redirect_uri(app)]

        client.store_registration_info(RegistrationRequest(**config))

        self.client = client
        self.client_registration_info = config
        self.logout_view = None
コード例 #7
0
ファイル: test_oic_provider.py プロジェクト: wxy148616/pyoidc
    def test_verify_sector_identifier_ru_ok(self):
        """Redirect_uris is present in the sector_identifier_uri content."""
        rr = RegistrationRequest(operation="register",
                                 sector_identifier_uri="https://example.com",
                                 redirect_uris=["http://example.com/present"])
        redirects = ["http://example.com/present"]

        with responses.RequestsMock() as rsps, LogCapture(
                level=logging.DEBUG) as logcap:
            rsps.add(rsps.GET,
                     "https://example.com",
                     body=json.dumps(redirects))
            si_redirects, si_url = self.provider._verify_sector_identifier(rr)

        assert si_url == "https://example.com"
        assert si_redirects == redirects
        assert len(logcap.records) == 2
        assert logcap.records[0].msg == "sector_identifier_uri => %s"
        assert logcap.records[0].args == ('["http://example.com/present"]', )
        assert logcap.records[1].msg == "redirect_uris: %s"
        assert logcap.records[1].args == (["http://example.com/present"], )
def test_dynamic_client(provider_info, browser):
    redirect_uri = "http://localhost"
    # Dynamic registration
    reg_req = RegistrationRequest(**{"redirect_uris": [redirect_uri], "response_types": ["id_token"]})
    resp = requests.post(reg_req.request(provider_info["registration_endpoint"]))
    reg_resp = RegistrationResponse().from_json(resp.text)

    # Authentication
    auth_req = AuthorizationRequest(
        **{"client_id": reg_resp["client_id"], "scope": "openid", "response_type": "id_token",
           "redirect_uri": redirect_uri, "state": "state0", "nonce": "nonce0"})
    browser.get(auth_req.request(provider_info["authorization_endpoint"]))
    fill_login_details(browser)

    # Authentication response
    urlencoded_resp = urlparse(browser.current_url).fragment
    auth_resp = AuthorizationResponse().from_urlencoded(urlencoded_resp)
    idt = IdToken().from_jwt(auth_resp["id_token"], verify=False)
    assert browser.current_url.startswith(redirect_uri)
    assert auth_resp["state"] == "state0"
    assert idt["nonce"] == "nonce0"
コード例 #9
0
ファイル: flask_pyoidc.py プロジェクト: jakabk/Flask-pyoidc
    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
コード例 #10
0
ファイル: app.py プロジェクト: johanlundberg/eduid-webapp
def init_oidc_client(app):
    oidc_client = Client(client_authn_method=CLIENT_AUTHN_METHOD)
    oidc_client.store_registration_info(
        RegistrationRequest(**app.config['CLIENT_REGISTRATION_INFO']))
    provider = app.config['PROVIDER_CONFIGURATION_INFO']['issuer']

    try:
        oidc_client.provider_config(provider)
    except ConnectionError:
        app.logger.warning(
            'No connection to provider {!s}. Can not start without provider configuration.'
            ' Retrying...'.format(provider))
        # Retry after 20 seconds
        sleep(20)  # Hack until we use new frontends
        try:
            oidc_client.provider_config(provider)
        except ConnectionError:
            app.logger.critical(
                'No connection to provider {!s}. Can not start without provider configuration.'
                ' Exiting.'.format(provider))
            exit(1)
    return oidc_client
コード例 #11
0
def init_oidc_client(app):
    oidc_client = Client(client_authn_method=CLIENT_AUTHN_METHOD)
    with app.app_context():
        try:
            app.config['AUTHORIZATION_RESPONSE_URI'] = url_for(
                'vetting.authorization_response')
        except BuildError as e:
            app.logger.error(
                'View vetting.authorization_response needs to be loaded or implemented.'
            )
            raise e
    oidc_client.store_registration_info(
        RegistrationRequest(**app.config['CLIENT_REGISTRATION_INFO']))
    provider = app.config['PROVIDER_CONFIGURATION_INFO']['issuer']
    try:
        oidc_client.provider_config(provider)
    except ConnectionError as e:
        app.logger.critical(
            'No connection to provider {!s}. Can not start without provider configuration.'
            .format(provider))
        raise e
    app.oidc_client = oidc_client
    return app
コード例 #12
0
ファイル: test_oic_message.py プロジェクト: atidev/pyoidc
 def test_registration_request(self):
     req = RegistrationRequest(
         operation="register",
         default_max_age=10,
         require_auth_time=True,
         default_acr="foo",
         application_type="web",
         redirect_uris=["https://example.com/authz_cb"])
     js = req.to_json()
     js_obj = json.loads(js)
     expected_js_obj = {
         "redirect_uris": ["https://example.com/authz_cb"],
         "application_type": "web",
         "default_acr": "foo",
         "require_auth_time": True,
         "operation": "register",
         "default_max_age": 10
     }
     assert js_obj == expected_js_obj
     assert query_string_compare(
         req.to_urlencoded(),
         "redirect_uris=https%3A%2F%2Fexample.com%2Fauthz_cb&application_type=web&default_acr=foo&require_auth_time=True&operation=register&default_max_age=10"
     )
コード例 #13
0
    def test_deserialize(self):
        msg = {
            "application_type": "web",
            "redirect_uris": ["https://client.example.org/callback",
                              "https://client.example.org/callback2"],
            "client_name": "My Example",
            "client_name#ja-Jpan-JP": "クライアント名",
            "logo_uri": "https://client.example.org/logo.png",
            "subject_type": "pairwise",
            "sector_identifier_uri":
                "https://other.example.net/file_of_redirect_uris.json",
            "token_endpoint_auth_method": "client_secret_basic",
            "jwks_uri": "https://client.example.org/my_public_keys.jwks",
            "userinfo_encrypted_response_alg": "RSA1_5",
            "userinfo_encrypted_response_enc": "A128CBC+HS256",
            "contacts": ["*****@*****.**", "*****@*****.**"],
            "request_uris": [
                "https://client.example.org/rf.txt"
                "#qpXaRLh_n93TTR9F252ValdatUQvQiJi5BDub2BeznA"]
        }

        reg = RegistrationRequest().deserialize(json.dumps(msg), "json")
        assert _eq(list(msg.keys()) + ['response_types'], reg.keys())
コード例 #14
0
def test_registration_request():
    req = RegistrationRequest(operation="register",
                              default_max_age=10,
                              require_auth_time=True,
                              default_acr="foo",
                              application_type="web",
                              redirect_uris=["https://example.com/authz_cb"])
    js = req.to_json()
    js_obj = json.loads(js)
    expected_js_obj = {
        "redirect_uris": ["https://example.com/authz_cb"],
        "application_type": "web",
        "default_acr": "foo",
        "require_auth_time": True,
        "operation": "register",
        "default_max_age": 10
    }
    assert js_obj == expected_js_obj
    ue = req.to_urlencoded()
    ue_splits = ue.split('&')
    expected_ue_splits = 'redirect_uris=https%3A%2F%2Fexample.com%2Fauthz_cb&application_type=web&default_acr=foo&require_auth_time=True&operation=register&default_max_age=10'.split(
        '&')
    assert _eq(ue_splits, expected_ue_splits)
コード例 #15
0
# -----------------------------------------------------------------------------
# The RP as federation entity
# -----------------------------------------------------------------------------

sunet_rp = Operator(iss='https://sunet.se/sysadm',
                    keyjar=build_keyjar(key_conf)[1])

# -----------------------------------------------------------------------------
# -- construct Registration Request to be signed by organisation
# -----------------------------------------------------------------------------

rreq = RegistrationRequest(
    redirect_uris=['https://sunet.se/rp1/callback'],
    application_type='web',
    response_types=['code'],
    signing_keys=sunet_rp.signing_keys_as_jwks(),
    jwks_uri_signed='https://sunet.se/rp1/jwks.jws'
)

print_request('Client Registration request', rreq)

# -----------------------------------------------------------------------------
# SUNET signs Registration Request once per federation
# -----------------------------------------------------------------------------

# adds the developers software statement
rreq.update({
    "metadata_statements": [sunet_swamid],
})
コード例 #16
0
    def registration_endpoint(self, request, authn=None, **kwargs):
        """
        Registration endpoint. This is where a registration request should
        be handled.

        :param request: The request, either as a dictionary or as a JSON
            document
        :param authn: Authentication information
        :param kwargs: Extra key work arguments.
        :return: A request response or an error response.
        """
        logger.debug("@registration_endpoint: <<{}>>".format(
            sanitize(request)))

        if isinstance(request, dict):
            request = ClientMetadataStatement(**request)
        else:
            try:
                request = ClientMetadataStatement().deserialize(
                    request, "json")
            except ValueError:
                request = ClientMetadataStatement().deserialize(request)

        if not self.is_federation_request(request):
            return provider.Provider.registration_endpoint(self,
                                                           request.to_json(),
                                                           authn=None,
                                                           **kwargs)

        try:
            request.verify()
        except Exception as err:
            return error('Invalid request')

        logger.info("registration_request:{}".format(
            sanitize(request.to_dict())))

        les = self.federation_entity.get_metadata_statement(
            request, 'registration')

        if les:
            ms = self.federation_entity.pick_by_priority(les)
            self.federation = ms.fo
        else:  # Nothing I can use
            return error(error='invalid_request',
                         descr='No signed metadata statement I could use')

        _pc = ms.protected_claims()
        if _pc:
            request = RegistrationRequest(**_pc)
        else:
            request = RegistrationRequest(
                **ms.unprotected_and_protected_claims())
        result = self.client_registration_setup(request)
        if 'signed_jwks_uri' in _pc:
            _kb = KeyBundle(source=_pc['signed_jwks_uri'],
                            verify_keys=ms.signing_keys,
                            verify_ssl=False)
            _kb.do_remote()
            replace_jwks_key_bundle(self.keyjar, result['client_id'], _kb)
            result['signed_jwks_uri'] = _pc['signed_jwks_uri']

        if isinstance(result, Response):
            return result

        # TODO This is where the OP should sign the response
        if ms.fo:
            _fo = ms.fo
            _sig = self._signer()

            if _sig:
                sms = _sig.create_signed_metadata_statement(result,
                                                            'response', [_fo],
                                                            single=True)
            else:
                raise SigningServiceError('No Signer')

            self.federation_entity.extend_with_ms(result, {_fo: sms})

        return Created(result.to_json(),
                       content="application/json",
                       headers=[("Cache-Control", "no-store")])
コード例 #17
0
TREQ = AccessTokenRequest(code="code",
                          redirect_uri="http://example.com/authz",
                          client_id=CLIENT_ID)

AREQ = AuthorizationRequest(response_type="code",
                            client_id="client_id",
                            redirect_uri="http://example.com/authz",
                            scope=["openid"],
                            state="state0",
                            nonce="N0nce")

UIREQ = UserInfoRequest(access_token="access_token")

REGREQ = RegistrationRequest(contacts=["*****@*****.**"],
                             redirect_uris=["http://example.org/jqauthz"],
                             application_name="pacubar",
                             client_id=CLIENT_ID,
                             operation="register",
                             application_type="web")

RSREQ = RefreshSessionRequest(id_token="id_token",
                              redirect_url="http://example.com/authz",
                              state="state0")

#key, type, usage, owner="."

alg = "HS256"
ktype = alg2keytype(alg)
keys = KC_SYM_S.get(ktype)
CSREQ = CheckSessionRequest(
    id_token=IDTOKEN.to_jwt(key=keys, algorithm="HS256"))
コード例 #18
0
    def test_full_flow(self, context, frontend):
        redirect_uri = "https://client.example.com/redirect"
        response_type = "code id_token token"
        mock_callback = Mock()
        frontend.auth_req_callback_func = mock_callback
        # discovery
        http_response = frontend.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.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",
            state="state",
            nonce="nonce")
        context.request = dict(parse_qsl(authn_req.to_urlencoded()))
        frontend.handle_authn_request(context)
        assert mock_callback.call_count == 1

        # fake authentication response from backend
        internal_response = self.setup_for_authn_response(
            context, frontend, authn_req)
        http_response = frontend.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.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.userinfo_endpoint(context)
        parsed = OpenIDSchema().deserialize(http_response.message, "json")
        assert "email" in parsed
コード例 #19
0
ファイル: test_oic_provider.py プロジェクト: wxy148616/pyoidc
    def test_verify_redirect_uri_native_custom(self):
        areq = RegistrationRequest(
            redirect_uris=["com.example.app:/oauth2redirect"],
            application_type='native')

        self.provider.verify_redirect_uris(areq)
コード例 #20
0
ファイル: test_oic_provider.py プロジェクト: wxy148616/pyoidc
    def test_verify_redirect_uri_native_loopback(self):
        areq = RegistrationRequest(redirect_uris=["http://127.0.0.1/cb"],
                                   application_type='native')

        self.provider.verify_redirect_uris(areq)
コード例 #21
0
ファイル: test_oic_provider.py プロジェクト: wxy148616/pyoidc
    def test_verify_redirect_uri_native_http_localhost(self):
        areq = RegistrationRequest(redirect_uris=["http://localhost/cb"],
                                   application_type='native')

        self.provider.verify_redirect_uris(areq)
コード例 #22
0
ファイル: provider.py プロジェクト: j-c-1253/oidctest
    def registration_endpoint(self, request, authn=None, **kwargs):
        try:
            reg_req = RegistrationRequest().deserialize(request, "json")
        except ValueError:
            reg_req = RegistrationRequest().deserialize(request)

        self.events.store(EV_PROTOCOL_REQUEST, reg_req)
        try:
            response_type_cmp(kwargs['test_cnf']['response_type'],
                              reg_req['response_types'])
        except KeyError:
            pass

        try:
            provider.Provider.verify_redirect_uris(reg_req)
        except InvalidRedirectURIError as err:
            return error(error="invalid_configuration_parameter",
                         descr="Invalid redirect_uri: {}".format(err))

        if "initiate_login_uri" in self.behavior_type:
            if not "initiate_login_uri" in reg_req:
                return error(
                    error="invalid_configuration_parameter",
                    descr=
                    "No \"initiate_login_uri\" endpoint found in the Client Registration Request\""
                )

        # Do initial verification that all endpoints from the client uses
        #  https
        for endp in ["jwks_uri", "initiate_login_uri"]:
            try:
                uris = reg_req[endp]
            except KeyError:
                continue

            if not isinstance(uris, list):
                uris = [uris]
            for uri in uris:
                if not uri.startswith("https://"):
                    return error(
                        error="invalid_configuration_parameter",
                        descr="Non-HTTPS endpoint in '{}'".format(endp))

        if not "contacts" in reg_req:
            return error(
                error="invalid_configuration_parameter",
                descr="No \"contacts\" claim provided in registration request."
            )
        elif not "@" in reg_req["contacts"][0]:
            return error(
                error="invalid_configuration_parameter",
                descr=
                "First address in \"contacts\" value in registration request is not a valid e-mail address."
            )

        _response = provider.Provider.registration_endpoint(
            self, request, authn, **kwargs)
        self.events.store(EV_HTTP_RESPONSE, _response)
        self.init_keys = []
        if "jwks_uri" in reg_req:
            if _response.status == "200 OK":
                # find the client id
                req_resp = RegistrationResponse().from_json(_response.message)
                for kb in self.keyjar[req_resp["client_id"]]:
                    if kb.imp_jwks:
                        self.events.store("Client JWKS", kb.imp_jwks)

        return _response
コード例 #23
0
# -----------------------------------------------------------------------------
# The RPs signing key
# -----------------------------------------------------------------------------

rp_jwks, rp_keyjar, _ = build_keyjar(key_conf)

print_private_key(rp_keyjar, "RPs signing key")

# -----------------------------------------------------------------------------
# -- construct Registration Request to be signed by Developer
# -----------------------------------------------------------------------------

rreq = RegistrationRequest(redirect_uris=['https://example.com/rp1/callback'],
                           application_type='web',
                           response_types=['code'],
                           signing_key=rp_jwks['keys'][0],
                           jwks_uri_signed='https://example.com/rp1/jwks.jws')

print(70 * "-")
print('Client Registration request')
print(70 * "-")
print_lines(
    json.dumps(rreq.to_dict(),
               sort_keys=True,
               indent=2,
               separators=(',', ': ')))

# -----------------------------------------------------------------------------
# Developer signs Registration Request once per federation
# -----------------------------------------------------------------------------
コード例 #24
0
 def test_registration_request_with_coupled_encryption_params(self, enc_param):
     registration_params = {"redirect_uris": ["https://example.com/authz_cb"], enc_param: "RS25asdasd6"}
     registration_req = RegistrationRequest(**registration_params)
     with pytest.raises(AssertionError):
         registration_req.verify()