コード例 #1
0
ファイル: test_oic_message.py プロジェクト: joostd/pyoidc
    def test_deserialize(self):
        msg = {
            "client_id": "s6BhdRkqt3",
            "client_secret": "ZJYCqe3GGRvdrudKyZS0XhGv_Z45DuKhCUk0gBR1vZk",
            "client_secret_expires_at": 1577858400,
            "registration_access_token": "this.is.an.access.token.value.ffx83",
            "registration_client_uri":
                "https://server.example.com/connect/register?client_id"
                "=s6BhdRkqt3",
            "token_endpoint_auth_method": "client_secret_basic",
            "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",
            "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"]
        }

        resp = RegistrationResponse().deserialize(json.dumps(msg), "json")
        assert _eq(msg.keys(), resp.keys())
コード例 #2
0
    def test_deserialize(self):
        msg = {
            "client_id": "s6BhdRkqt3",
            "client_secret": "ZJYCqe3GGRvdrudKyZS0XhGv_Z45DuKhCUk0gBR1vZk",
            "client_secret_expires_at": 1577858400,
            "registration_access_token": "this.is.an.access.token.value.ffx83",
            "registration_client_uri":
                "https://server.example.com/connect/register?client_id"
                "=s6BhdRkqt3",
            "token_endpoint_auth_method": "client_secret_basic",
            "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",
            "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"]
        }

        resp = RegistrationResponse().deserialize(json.dumps(msg), "json")
        assert _eq(msg.keys(), resp.keys())
コード例 #3
0
ファイル: test_oic_provider.py プロジェクト: atidev/pyoidc
    def test_registration_endpoint_openid4us(self):
        req = RegistrationRequest(
            **{'token_endpoint_auth_method': u'client_secret_post',
               'redirect_uris': [
                   u'https://connect.openid4.us:5443/phpRp/index.php/callback',
                   u'https://connect.openid4.us:5443/phpRp/authcheck.php/authcheckcb'],
               'jwks_uri': u'https://connect.openid4.us:5443/phpRp/rp/rp.jwk',
               'userinfo_encrypted_response_alg': u'RSA1_5',
               'contacts': [u'*****@*****.**'],
               'userinfo_encrypted_response_enc': u'A128CBC-HS256',
               'application_type': u'web',
               'client_name': u'ABRP-17',
               'grant_types': [u'authorization_code', u'implicit'],
               'post_logout_redirect_uris': [
                   u'https://connect.openid4.us:5443/phpRp/index.php/logoutcb'],
               'subject_type': u'public',
               'response_types': [u'code', u'token', u'id_token', u'code token',
                                  u'code id_token', u'id_token token',
                                  u'code id_token token'],
               'policy_uri': u'https://connect.openid4.us:5443/phpRp/index.php/policy',
               'logo_uri': u'https://connect.openid4.us:5443/phpRp/media/logo.png'})

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

        regresp = RegistrationResponse().deserialize(resp.message, "json")
        assert _eq(regresp.keys(), list(req.keys()) +
                   ['registration_client_uri',
                    'client_secret_expires_at',
                    'registration_access_token',
                    'client_id', 'client_secret',
                    'client_id_issued_at'])
コード例 #4
0
ファイル: provider.py プロジェクト: wayward710/pyoidc
    def read_registration(self, authn, request, **kwargs):
        """
        Read all information this server has on a client.
        Authorization is done by using the access token that was return as
        part of the client registration result.

        :param authn: The Authorization HTTP header
        :param request: The query part of the URL
        :param kwargs: Any other arguments
        :return:
        """

        logger.debug("authn: %s, request: %s" % (authn, request))

        # verify the access token, has to be key into the client information
        # database.
        assert authn.startswith("Bearer ")
        token = authn[len("Bearer "):]

        client_id = self.cdb[token]

        # extra check
        _info = urlparse.parse_qs(request)
        assert _info["client_id"][0] == client_id

        logger.debug("Client '%s' reads client info" % client_id)
        args = dict([(k, v) for k, v in self.cdb[client_id].items()
                     if k in RegistrationResponse.c_param])

        self.comb_redirect_uris(args)
        response = RegistrationResponse(**args)

        return Response(response.to_json(), content="application/json",
                        headers=[("Cache-Control", "no-store")])
コード例 #5
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",
            ],
        )
コード例 #6
0
ファイル: oidc.py プロジェクト: borgand/SATOSA
    def _fixup_registration_response(self, http_resp):
        # remove client_secret since no token endpoint is published
        response = RegistrationResponse().deserialize(http_resp.message, "json")
        del response["client_secret"]
        # specify supported id token signing alg
        response["id_token_signed_response_alg"] = self.sign_alg

        http_resp.message = response.to_json()
        return http_resp
コード例 #7
0
    def refresh_session_endpoint(self, query):
        self.parse_refresh_session_request(query=query)

        resp = RegistrationResponse(client_id="anonymous",
                                    client_secret="hemligt")

        response = Response()
        response.headers = {"content-type": "application/json"}
        response.text = resp.to_json()
        return response
コード例 #8
0
    def refresh_session_endpoint(self, query):
        self.parse_refresh_session_request(query=query)

        resp = RegistrationResponse(client_id="anonymous",
                                    client_secret="hemligt")

        response = Response()
        response.headers = {"content-type": "application/json"}
        response.text = resp.to_json()
        return response
コード例 #9
0
ファイル: oidc.py プロジェクト: borgand/SATOSA
    def _fixup_registration_response(self, http_resp):
        # remove client_secret since no token endpoint is published
        response = RegistrationResponse().deserialize(http_resp.message,
                                                      "json")
        del response["client_secret"]
        # specify supported id token signing alg
        response["id_token_signed_response_alg"] = self.sign_alg

        http_resp.message = response.to_json()
        return http_resp
コード例 #10
0
ファイル: base.py プロジェクト: JustKiddingCode/arpoc
 def create_client_from_secrets(self, name: str,
                                provider: config.ProviderConfig) -> None:
     """ Try to create an openid connect client from the secrets that are
         saved in the secrets file"""
     client_secrets = self._secrets[name]
     client = oic.oic.Client(client_authn_method=CLIENT_AUTHN_METHOD)
     client.provider_config(provider.configuration_url)
     client_reg = RegistrationResponse(**client_secrets)
     client.store_registration_info(client_reg)
     client.redirect_uris = client_secrets['redirect_uris']
     self.__oidc_provider[name] = client
     self._secrets[name] = client_reg.to_dict()
コード例 #11
0
ファイル: test_oic_provider.py プロジェクト: wxy148616/pyoidc
    def test_registration_endpoint_unicode(self):
        data = 'application_type=web&client_name=M%C3%A1+supe%C5%99+service&' \
               'redirect_uris=http%3A%2F%2Fexample.com%2Fauthz&response_types=code'
        resp = self.provider.registration_endpoint(request=data)

        regresp = RegistrationResponse().deserialize(resp.message, "json")
        assert _eq(regresp.keys(), [
            'redirect_uris', 'application_type', 'client_name',
            'registration_client_uri', 'client_secret_expires_at',
            'registration_access_token', 'client_id', 'client_secret',
            'client_id_issued_at', 'response_types'
        ])
コード例 #12
0
    def test_read_registration(self):
        rr = RegistrationRequest(operation="register",
                                 redirect_uris=["http://example.org/new"],
                                 response_types=["code"])
        registration_req = rr.to_json()
        resp = self.provider.registration_endpoint(request=registration_req)
        regresp = RegistrationResponse().from_json(resp.message)

        authn = ' '.join(['Bearer', regresp['registration_access_token']])
        query = '='.join(['client_id', regresp['client_id']])
        resp = self.provider.read_registration(authn, query)

        assert json.loads(resp.message) == regresp.to_dict()
コード例 #13
0
    def test_read_registration(self):
        rr = RegistrationRequest(
            operation="register", redirect_uris=["http://example.org/new"], response_types=["code"]
        )
        registration_req = rr.to_json()
        resp = self.provider.registration_endpoint(request=registration_req)
        regresp = RegistrationResponse().from_json(resp.message)

        authn = " ".join(["Bearer", regresp["registration_access_token"]])
        query = "=".join(["client_id", regresp["client_id"]])
        resp = self.provider.read_registration(authn, query)

        assert json.loads(resp.message) == regresp.to_dict()
コード例 #14
0
ファイル: FakeOp.py プロジェクト: borgand/SATOSA
 def setup_client_registration_endpoint(self):
     client_info = TestConfiguration.get_instance().rp_config.CLIENTS[PROVIDER]["client_info"]
     request = RegistrationRequest().deserialize(json.dumps(client_info), "json")
     _cinfo = self.provider.do_client_registration(request, CLIENT_ID)
     args = dict([(k, v) for k, v in _cinfo.items()
                  if k in RegistrationResponse.c_param])
     args['client_id'] = CLIENT_ID
     self.provider.comb_uri(args)
     registration_response = RegistrationResponse(**args)
     responses.add(
         responses.POST,
         self.op_base + "registration",
         body=registration_response.to_json(),
         status=200,
         content_type='application/json')
コード例 #15
0
    def test_registered_redirect_uri_with_query_component(self):
        provider2 = Provider("FOOP", {}, {}, None, None, None, None, "")

        rr = RegistrationRequest(
            operation="register",
            redirect_uris=["http://example.org/cb?foo=bar"],
            response_types=["code"])

        registration_req = rr.to_json()
        resp = provider2.registration_endpoint(request=registration_req)

        regresp = RegistrationResponse().from_json(resp.message)

        print regresp.to_dict()

        faulty = [
            "http://example.org/cb", "http://example.org/cb/foo",
            "http://example.org/cb?got=you", "http://example.org/cb?foo=you"
            "http://example.org/cb?foo=bar&got=you",
            "http://example.org/cb?foo=you&foo=bar"
        ]
        correct = [
            "http://example.org/cb?foo=bar",
        ]

        cid = regresp["client_id"]

        for ruri in faulty:
            areq = AuthorizationRequest(redirect_uri=ruri,
                                        client_id=cid,
                                        scope="openid",
                                        response_type="code")

            print areq
            try:
                provider2._verify_redirect_uri(areq)
            except RedirectURIError:
                pass

        for ruri in correct:
            areq = AuthorizationRequest(redirect_uri=ruri,
                                        client_id=cid,
                                        scope="openid",
                                        response_type="code")

            resp = provider2._verify_redirect_uri(areq)
            print resp
            assert resp is None
コード例 #16
0
    def test_registered_redirect_uri_with_query_component(self):
        provider2 = Provider("FOOP", {}, {}, None, None, None, None, "")

        rr = RegistrationRequest(operation="register",
                                 redirect_uris=["http://example.org/cb?foo=bar"],
                                 response_types=["code"])

        registration_req = rr.to_json()
        resp = provider2.registration_endpoint(request=registration_req)

        regresp = RegistrationResponse().from_json(resp.message)

        print regresp.to_dict()

        faulty = [
            "http://example.org/cb",
            "http://example.org/cb/foo",
            "http://example.org/cb?got=you",
            "http://example.org/cb?foo=you"
            "http://example.org/cb?foo=bar&got=you",
            "http://example.org/cb?foo=you&foo=bar"
        ]
        correct = [
            "http://example.org/cb?foo=bar",
        ]

        cid = regresp["client_id"]

        for ruri in faulty:
            areq = AuthorizationRequest(redirect_uri=ruri,
                                        client_id=cid,
                                        scope="openid",
                                        response_type="code")

            print areq
            try:
                provider2._verify_redirect_uri(areq)
            except RedirectURIError:
                pass

        for ruri in correct:
            areq = AuthorizationRequest(redirect_uri=ruri,
                                        client_id=cid, scope="openid",
                                        response_type="code")

            resp = provider2._verify_redirect_uri(areq)
            print resp
            assert resp is None
コード例 #17
0
def oidc_login():
    state = rndstr()
    nonce = rndstr()
    client = Client(client_authn_method=CLIENT_AUTHN_METHOD)

    client.provider_config(OIDC_INFO_URL)

    info = {"client_id": CLIENT_ID, "client_secret": CLIENT_SECRET}
    client_reg = RegistrationResponse(**info)
    client.store_registration_info(client_reg)

    args = {
        "client_id": client.client_id,
        "response_type": "code",
        "scope": ["openid"],
        "nonce": nonce,
        "redirect_uri": OIDC_REDIRECT_URI,
        "state": state
    }

    auth_req = client.construct_AuthorizationRequest(request_args=args)
    login_url = auth_req.request(client.authorization_endpoint)

    # Save in cache Key: state => Value: nonce
    current_app.cache.set(state, nonce)

    return redirect(login_url, 303)
コード例 #18
0
def test_scope_who_am_i(provider):
    registration_params = {
        "application_type": "web",
        "response_types": ["code", "token"],
        "redirect_uris": "http://example.org"
    }
    reg_req = RegistrationRequest(**registration_params)
    resp = provider.registration_endpoint(reg_req.to_urlencoded())
    reg_resp = RegistrationResponse().from_json(resp.message)

    auth_req = AuthorizationRequest(
        **{
            "client_id": reg_resp["client_id"],
            "scope": "openid who_am_i",
            "response_type": "code token",
            "redirect_uri": "http://example.org",
            "state": "state0",
            "nonce": "nonce0"
        })
    resp = provider.authorization_endpoint(auth_req.to_urlencoded())
    auth_resp = AuthorizationResponse().from_urlencoded(resp.message)

    userinfo_req = UserInfoRequest(
        **{"access_token": auth_resp["access_token"]})
    resp = provider.userinfo_endpoint(userinfo_req.to_urlencoded())
    userinfo_resp = AuthorizationResponse().from_json(resp.message)

    assert userinfo_resp["given_name"] == "Bruce"
    assert userinfo_resp["family_name"] == "Lee"
コード例 #19
0
    def init_oic(self, provider_name):
        if provider_name not in PROVIDER_URL_MAP:
            raise ValueError('Invalid provider: %s', provider_name)
        provider = PROVIDER_URL_MAP[provider_name]
        self.scopes = ['openid', 'profile', 'email']
        db = SessionStore(self.db)
        client = Consumer(db, consumer_config, client_config=client_config)
        client.allow['issuer_mismatch'] = True

        # Github does not support dynamically resolving OpenID configuration.
        if provider_name == PROVIDER_GITHUB:
            self.scopes = ['user:email', 'read:user']
            client.provider_info = {
                'authorization_endpoint':
                'https://github.com/login/oauth/authorize',
                'token_endpoint':
                'https://github.com/login/oauth/access_token',
            }
            client.handle_provider_config(client.provider_info, 'GitHub')
        else:
            client.provider_info = client.provider_config(provider)

        providers = self.db.oic_registration.filter(None, {'issuer': provider})
        assert len(providers) == 1
        provider = self.db.oic_registration.getnode(providers[0])
        client_reg = RegistrationResponse(
            client_id=provider['client_id'],
            client_secret=provider['client_secret'])
        client.store_registration_info(client_reg)
        return client
コード例 #20
0
ファイル: provider.py プロジェクト: valintepes/pyop
    def handle_client_registration_request(self, request, http_headers=None):
        # type: (Optional[str], Optional[Mapping[str, str]]) -> oic.oic.message.RegistrationResponse
        """
        Handles a client registration request.
        :param request: JSON request from POST body
        :param http_headers: http headers
        """
        registration_req = RegistrationRequest().deserialize(request, 'json')

        for validator in self.registration_request_validators:
            validator(registration_req)
        logger.debug('parsed authentication_request: %s', registration_req)

        client_id, client_secret = self._issue_new_client()
        credentials = {
            'client_id': client_id,
            'client_id_issued_at': int(time.time()),
            'client_secret': client_secret,
            'client_secret_expires_at': 0  # never expires
        }

        response_params = self.match_client_preferences_with_provider_capabilities(
            registration_req)
        response_params.update(credentials)
        self.clients[client_id] = copy.deepcopy(response_params)

        registration_resp = RegistrationResponse(**response_params)
        logger.debug('registration_resp=%s from registration_req=%s',
                     registration_resp, registration_req)
        return registration_resp
コード例 #21
0
ファイル: provider.py プロジェクト: travisspencer/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))

        # 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
コード例 #22
0
ファイル: FakeOp.py プロジェクト: borgand/SATOSA
 def setup_client_registration_endpoint(self):
     client_info = TestConfiguration.get_instance(
     ).rp_config.CLIENTS[PROVIDER]["client_info"]
     request = RegistrationRequest().deserialize(json.dumps(client_info),
                                                 "json")
     _cinfo = self.provider.do_client_registration(request, CLIENT_ID)
     args = dict([(k, v) for k, v in _cinfo.items()
                  if k in RegistrationResponse.c_param])
     args['client_id'] = CLIENT_ID
     self.provider.comb_uri(args)
     registration_response = RegistrationResponse(**args)
     responses.add(responses.POST,
                   self.op_base + "registration",
                   body=registration_response.to_json(),
                   status=200,
                   content_type='application/json')
コード例 #23
0
ファイル: methods.py プロジェクト: dtougas/tortuga
    def _configure_client(self):
        config_file_path = JwtAuthenticationMethod.openid_client_config_path()

        if not os.path.exists(config_file_path):
            logger.info(
                'OpenID Connect configuration ({}) not found, JWT'
                ' authentication is disabled'.format(config_file_path)
            )

            return

        with open(config_file_path) as fp:
            config = json.loads(fp.read())

            self._client = Client(
                client_authn_method=CLIENT_AUTHN_METHOD,
                verify_ssl='/etc/pki/tls/certs/ca-bundle.crt'
            )

            self._client.provider_config(config['issuer'])

            client_registration = RegistrationResponse(
                client_id=config['client_id'],
                client_secret=config['client_secret']
            )

            self._client.store_registration_info(client_registration)
コード例 #24
0
ファイル: oidc.py プロジェクト: AnyBlok/Anyblok_Pyramid
def get_client():
    """Method that prepare the oidc client.

    This method use lru_cache in order call the OIDC provider once
    per thread

    Today we only support OIDC providers (ISSUER) that expose a
    /.well-known/openid-configuration route

    At the moment to authenticate the RP to the OIDC provider we only
    support through client_id/secret_ID/rp_callback attributes.

    You must configure OIDC in AnyBlok configuration:

    * **oidc-provider-issuer**: The OIDC Provider urls
        (ie: https://gitlab.com)
    * **oidc-relying-party-callback**: The Relaying Party callback, once
        the user is authenticate against the OIDC provider he will be redirect
        to that uri to the RP service (ie: http://localhost:8080/callback).
        In general this value is also configured in your OIDC provider to
        avoid redirection issues.
    * **oidc-relying-party-client-id**: The client id provide by your OIDC
        provider
    * **oidc-relying-party-secret-id**: The secret id provide by your OIDC
        provider

    And optionally:

    * **oidc-scope**: Specify what access privileges are being requested for
        Access Tokens. `cf Requesting claims using scope values
        <https://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims`_.
        a list of claims using coma separator. (default value: `openid,email`)
    * **oidc-userinfo-field**: Specify which field to use from the response
        of the OIDC provider `userinfo endpoint <https://openid.net/specs/
        openid-connect-core-1_0.html#UserInfoResponse>`_. To make sure
        it's a known user. (default value: `email`).
    """

    client = Client(client_authn_method=CLIENT_AUTHN_METHOD)
    for config in [
            "oidc_provider_issuer",
            "oidc_relying_party_client_id",
            "oidc_relying_party_secret_id",
            "oidc_relying_party_callback",
    ]:
        if Configuration.get(config, None) is None:
            raise ValueError("You must provide {} parameter".format(config))
    provider_info = client.provider_config(
        Configuration.get("oidc_provider_issuer"))
    info = {
        "client_id": Configuration.get("oidc_relying_party_client_id"),
        "client_secret": Configuration.get("oidc_relying_party_secret_id"),
        "redirect_uris": [Configuration.get("oidc_relying_party_callback")],
    }
    info.update(provider_info._dict)
    client_reg = RegistrationResponse(**info)

    client.store_registration_info(client_reg)
    return client
コード例 #25
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
コード例 #26
0
def oidc_client(webserver, oidc_provider, reverse):
    client = Client(client_authn_method=CLIENT_AUTHN_METHOD)
    client.provider_config(issuer=reverse("openid"))
    client.store_registration_info(
        RegistrationResponse(client_id=oidc_provider.client_id,
                             client_secret=oidc_provider.client_secret))

    return client
コード例 #27
0
    def registration_endpoint(self, data):
        try:
            req = self.parse_registration_request(data, "json")
        except ValueError:
            req = self.parse_registration_request(data)

        client_secret = rndstr()
        expires = utc_time_sans_frac() + self.registration_expires_in
        kwargs = {}
        if "client_id" not in req:
            client_id = rndstr(10)
            registration_access_token = rndstr(20)
            _client_info = req.to_dict()
            kwargs.update(_client_info)
            _client_info.update({
                "client_secret": client_secret,
                "info": req.to_dict(),
                "expires": expires,
                "registration_access_token": registration_access_token,
                "registration_client_uri": "register_endpoint"
            })
            self.client[client_id] = _client_info
            kwargs["registration_access_token"] = registration_access_token
            kwargs["registration_client_uri"] = "register_endpoint"
            try:
                del kwargs["operation"]
            except KeyError:
                pass
        else:
            client_id = req.client_id
            _cinfo = self.client[req.client_id]
            _cinfo["info"].update(req.to_dict())
            _cinfo["client_secret"] = client_secret
            _cinfo["expires"] = expires

        resp = RegistrationResponse(client_id=client_id,
                                    client_secret=client_secret,
                                    client_secret_expires_at=expires,
                                    **kwargs)

        response = Response()
        response.headers = {"content-type": "application/json"}
        response.text = resp.to_json()

        return response
コード例 #28
0
    def registration_endpoint(self, data):
        try:
            req = self.parse_registration_request(data, "json")
        except ValueError:
            req = self.parse_registration_request(data)

        client_secret = rndstr()
        expires = utc_time_sans_frac() + self.registration_expires_in
        kwargs = {}
        if "client_id" not in req:
            client_id = rndstr(10)
            registration_access_token = rndstr(20)
            _client_info = req.to_dict()
            kwargs.update(_client_info)
            _client_info.update({
                "client_secret": client_secret,
                "info": req.to_dict(),
                "expires": expires,
                "registration_access_token": registration_access_token,
                "registration_client_uri": "register_endpoint"
            })
            self.client[client_id] = _client_info
            kwargs["registration_access_token"] = registration_access_token
            kwargs["registration_client_uri"] = "register_endpoint"
            try:
                del kwargs["operation"]
            except KeyError:
                pass
        else:
            client_id = req.client_id
            _cinfo = self.client[req.client_id]
            _cinfo["info"].update(req.to_dict())
            _cinfo["client_secret"] = client_secret
            _cinfo["expires"] = expires

        resp = RegistrationResponse(client_id=client_id,
                                    client_secret=client_secret,
                                    client_secret_expires_at=expires,
                                    **kwargs)

        response = Response()
        response.headers = {"content-type": "application/json"}
        response.text = resp.to_json()

        return response
コード例 #29
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'
        ])
コード例 #30
0
ファイル: __init__.py プロジェクト: ghedin/pyoidc
    def handle_registration_info(self, response):
        if response.status_code == 200:
            resp = RegistrationResponse().deserialize(response.text, "json")
            self.store_registration_info(resp)
        else:
            err = ErrorResponse().deserialize(response.text, "json")
            raise PyoidcError("Registration failed: %s" % err.get_json())

        return resp
コード例 #31
0
ファイル: test_oic_consumer.py プロジェクト: smkent/pyoidc
    def test_complete_auth_token_idtoken(self):
        _state = "state0"
        self.consumer.consumer_config["response_type"] = ["id_token", "token"]
        self.consumer.registration_response = RegistrationResponse(
            id_token_signed_response_alg="HS256")
        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)
        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)
コード例 #32
0
ファイル: oper.py プロジェクト: keithuber/oidctest
 def run(self):
     if self.dynamic:
         self.catch_exception_and_error(self.conv.entity.register,
                                        **self.req_args)
     else:
         self.conv.events.store(EV_NOOP, "Dynamic registration")
         self.conv.entity.store_registration_info(
             RegistrationResponse(
                 **self.conv.entity_config["registration_response"]))
コード例 #33
0
 def _store_registration_info(self, client_metadata):
     registration_response = RegistrationResponse(**client_metadata)
     self._client.store_registration_info(registration_response)
     self._client_extension.store_registration_info(registration_response)
     # Set client_id and client_secret for _oauth2_client. This is used
     # by Client Credentials Flow.
     self._oauth2_client.client_id = registration_response['client_id']
     self._oauth2_client.client_secret = registration_response[
         'client_secret']
コード例 #34
0
ファイル: views.py プロジェクト: ARGOeu/b2note
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
コード例 #35
0
ファイル: test_oic_provider.py プロジェクト: asheidan/pyoidc
def test_registered_redirect_uri_with_query_component():
    provider2 = Provider("FOOP", {}, {}, None, None)
    environ = {}

    rr = RegistrationRequest(operation="register",
                             redirect_uris=["http://example.org/cb?foo=bar"])

    registration_req = rr.to_urlencoded()
    resp = provider2.registration_endpoint(environ, start_response,
                                    query=registration_req)

    regresp = RegistrationResponse().from_json(resp[0])

    print regresp.to_dict()

    faulty = [
        "http://example.org/cb",
        "http://example.org/cb/foo",
        "http://example.org/cb?got=you",
        "http://example.org/cb?foo=you"
    ]
    correct = [
        "http://example.org/cb?foo=bar",
        "http://example.org/cb?foo=bar&got=you",
        "http://example.org/cb?foo=bar&foo=you"
    ]

    for ruri in faulty:
        areq = AuthorizationRequest(redirect_uri=ruri,
                                    client_id=regresp["client_id"],
                                    scope="openid",
                                    response_type="code")

        print areq
        assert provider2._verify_redirect_uri(areq) != None


    for ruri in correct:
        areq = AuthorizationRequest(redirect_uri= ruri,
                                    client_id=regresp["client_id"])

        resp = provider2._verify_redirect_uri(areq)
        print resp
        assert resp == None
コード例 #36
0
def oidc_callback():
    # Instantiate again the client

    client = Client(client_authn_method=CLIENT_AUTHN_METHOD)
    info = {"client_id": CLIENT_ID, "client_secret": CLIENT_SECRET}
    client_reg = RegistrationResponse(**info)
    client.store_registration_info(client_reg)

    args = {
        "client_id": client.client_id,
        "response_type": "code",
        "scope": ["openid"],
        "redirect_uri": OIDC_REDIRECT_URI,
    }

    auth_req = client.construct_AuthorizationRequest(request_args=args)
    client.provider_config(OIDC_INFO_URL)

    # Posted information
    query_string = request.url
    auth_response = client.parse_response(AuthorizationResponse,
                                          info=query_string,
                                          sformat="urlencoded")

    # We need to find a state/nonce pair that matches what we have
    nonce = current_app.cache.get(auth_response['state'])
    current_app.cache.delete(auth_response['state'])

    if "id_token" in auth_response and auth_response["id_token"][
            "nonce"] != nonce:
        return make_response('', 500)

    # Request an access token an use it to require the user's information
    args = {"code": auth_response["code"]}

    client.do_access_token_request(state=auth_response["state"],
                                   request_args=args,
                                   authn_method="client_secret_basic")

    # This is the object with the user info
    user_info = client.do_user_info_request(state=auth_response["state"])

    # Take the mail depending on the attribute they have saved it in
    mail = user_info[u'mail']
    if not mail:
        mail = user_info[u'email']

    # Validate that the user mail is in the DB
    user = User.query.filter_by(email=mail).first()
    if user is None:
        return make_response('Unauthorized user', 401)

    # Login the user and return
    login_user(user, remember=True)

    return redirect(url_for('welcome'))
コード例 #37
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
コード例 #38
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
コード例 #39
0
ファイル: openid.py プロジェクト: wotaen/openlobby-server
def init_client_for_shortcut(openid_client_obj):
    client = Client(client_authn_method=CLIENT_AUTHN_METHOD)
    reg_info = {
        'client_id': openid_client_obj.client_id,
        'client_secret': openid_client_obj.client_secret,
        'redirect_uris': [settings.REDIRECT_URI],
    }
    client_reg = RegistrationResponse(**reg_info)
    client.store_registration_info(client_reg)
    client.provider_config(openid_client_obj.issuer)
    return client
コード例 #40
0
    def test_register_client(self, context, frontend):
        redirect_uri = "https://client.example.com"
        registration_request = RegistrationRequest(redirect_uris=[redirect_uri],
                                                   response_types=["id_token"])
        context.request = registration_request.to_dict()
        registration_response = frontend.client_registration(context)
        assert registration_response.status == "201 Created"

        reg_resp = RegistrationResponse().deserialize(registration_response.message, "json")
        assert "client_id" in reg_resp
        assert reg_resp["redirect_uris"] == [redirect_uri]
        assert reg_resp["response_types"] == ["id_token"]
コード例 #41
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"]

        print req.to_dict()

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

        print resp.message
        regresp = RegistrationResponse().deserialize(resp.message, "json")
        print regresp.keys()
        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'])
コード例 #42
0
ファイル: test_oic_provider.py プロジェクト: asheidan/pyoidc
def test_registration_endpoint():
    server = provider_init

    req = RegistrationRequest(operation="register")

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

    environ = BASE_ENVIRON.copy()
    environ["QUERY_STRING"] = req.to_urlencoded()

    resp = server.registration_endpoint(environ, start_response)

    print resp
    regresp = RegistrationResponse().deserialize(resp[0], "json")
    print regresp.keys()
    assert _eq(regresp.keys(), ['redirect_uris', 'application_type',
                                'expires_at', 'registration_access_token',
                                'client_id', 'client_secret', 'client_name',
                                "contacts"])

    # --- UPDATE ----

    req = RegistrationRequest(operation="client_update")
    req["application_type"] = "web"
    req["client_name"] = "My super duper service"
    req["redirect_uris"] = ["http://example.com/authz"]
    req["contacts"] = ["*****@*****.**"]

    environ = BASE_ENVIRON.copy()
    environ["QUERY_STRING"] = req.to_urlencoded()
    environ["HTTP_AUTHORIZATION"] = "Bearer %s" % regresp["registration_access_token"]

    resp = server.registration_endpoint(environ, start_response)

    print resp
    update = RegistrationResponse().deserialize(resp[0], "json")
    print update.keys()
    assert _eq(update.keys(), ['redirect_uris', 'application_type',
                               'expires_at', 'registration_access_token',
                               'client_id', 'client_secret', 'client_name',
                               'contacts'])
コード例 #43
0
ファイル: provider.py プロジェクト: wayward710/pyoidc
            "client_id_issued_at": utc_time_sans_frac()}

        self.cdb[_rat] = client_id

        _cinfo = self.do_client_registration(request, client_id,
                                             ignore=["redirect_uris",
                                                     "policy_url",
                                                     "logo_url"])
        if isinstance(_cinfo, Response):
            return _cinfo

        args = dict([(k, v) for k, v in _cinfo.items()
                     if k in RegistrationResponse.c_param])

        self.comb_redirect_uris(args)
        response = RegistrationResponse(**args)

        self.keyjar.load_keys(request, client_id)

        # Add the key to the keyjar
        if client_secret:
            _kc = KeyBundle([{"kty": "oct", "key": client_secret,
                              "use": "ver"},
                             {"kty": "oct", "key": client_secret,
                              "use": "sig"}])
            try:
                _keyjar[client_id].append(_kc)
            except KeyError:
                _keyjar[client_id] = [_kc]

        self.cdb[client_id] = _cinfo