コード例 #1
0
ファイル: provider.py プロジェクト: imsoftware/pyoidc
    def registration_endpoint(self, environ, start_response, **kwargs):
        logger.debug("@registration_endpoint")
        try:
            query = kwargs["query"]
        except KeyError:
            try:
                query = get_or_post(environ)
            except UnsupportedMethod:
                resp = BadRequest("Unsupported method")
                return resp(environ, start_response)

        request = RegistrationRequest().deserialize(query, "urlencoded")
        logger.info("registration_request:%s" % request.to_dict())

        _keystore = self.server.keystore
        if request["type"] == "client_associate":
            # create new id och secret
            client_id = rndstr(12)
            while client_id in self.cdb:
                client_id = rndstr(12)

            client_secret = secret(self.seed, client_id)
            self.cdb[client_id] = {
                "client_secret":client_secret
            }
            _cinfo = self.cdb[client_id]

            if "redirect_uris" in request:
                for uri in request["redirect_uris"]:
                    if urlparse.urlparse(uri).fragment:
                        err = ClientRegistrationErrorResponse(
                                    error="invalid_configuration_parameter",
                            error_description="redirect_uri contains fragment")
                        resp = Response(err.to_json(),
                                        content="application/json",
                                        status="400 Bad Request")
                        return resp(environ, start_response)

            for key,val in request.items():
                _cinfo[key] = val

            try:
                self.keystore.load_keys(request, client_id)
            except Exception, err:
                logger.error("Failed to load client keys: %s" % request.to_dict())
                err = ClientRegistrationErrorResponse(
                        error="invalid_configuration_parameter",
                        error_description="%s" % err)
                resp = Response(err.to_json(), content="application/json",
                                status="400 Bad Request")
                return resp(environ, start_response)

            response = RegistrationResponseCARS(client_id=client_id)
コード例 #2
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
コード例 #3
0
 def test_register_client_with_wrong_response_type(self, context, frontend):
     redirect_uri = "https://client.example.com"
     registration_request = RegistrationRequest(redirect_uris=[redirect_uri], response_types=["id_token token"])
     context.request = registration_request.to_dict()
     registration_response = frontend.client_registration(context)
     assert registration_response.status == "400 Bad Request"
     error_response = ClientRegistrationErrorResponse().deserialize(registration_response.message, "json")
     assert error_response["error"] == "invalid_request"
     assert "response_type" in error_response["error_description"]
コード例 #4
0
 def test_register_client_with_wrong_response_type(self, context, frontend):
     redirect_uri = "https://client.example.com"
     registration_request = RegistrationRequest(
         redirect_uris=[redirect_uri], response_types=["id_token token"])
     context.request = registration_request.to_dict()
     registration_response = frontend.client_registration(context)
     assert registration_response.status == "400 Bad Request"
     error_response = ClientRegistrationErrorResponse().deserialize(
         registration_response.message, "json")
     assert error_response["error"] == "invalid_request"
     assert "response_type" in error_response["error_description"]
コード例 #5
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"]
コード例 #6
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
コード例 #7
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"]
コード例 #8
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'])
コード例 #9
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'
        ])
コード例 #10
0
ファイル: test_oidc.py プロジェクト: borgand/SATOSA
    def test_register_client(self):
        redirect_uri = "https://client.example.com"
        registration_request = RegistrationRequest(redirect_uris=[redirect_uri],
                                                   response_types=["id_token"])
        context = Context()
        context.request = registration_request.to_dict()
        registration_response = self.instance._register_client(context)
        assert registration_response.status == "201 Created"

        reg_resp = RegistrationResponse().deserialize(registration_response.message, "json")
        assert "client_id" in reg_resp
        assert reg_resp["client_id"] in self.instance.provider.cdb
        # no need to issue client secret since to token endpoint is published
        assert "client_secret" not in reg_resp
        assert reg_resp["redirect_uris"] == [redirect_uri]
        assert reg_resp["response_types"] == ["id_token"]
        assert reg_resp["id_token_signed_response_alg"] == "RS256"
コード例 #11
0
ファイル: provider.py プロジェクト: wayward710/pyoidc
    def l_registration_endpoint(self, request, authn=None, **kwargs):
        _log_debug = logger.debug
        _log_info = logger.info

        _log_debug("@registration_endpoint")

        request = RegistrationRequest().deserialize(request, "json")

        _log_info("registration_request:%s" % request.to_dict())
        resp_keys = request.keys()

        try:
            request.verify()
        except MessageException, err:
            if "type" not in request:
                return self._error(error="invalid_type", 
                                   descr="%s" % err)
            else:
                return self._error(error="invalid_configuration_parameter",
                                   descr="%s" % err)
コード例 #12
0
# -----------------------------------------------------------------------------
# -- 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
# -----------------------------------------------------------------------------

# adds the developers software statement
rreq.update({
    "software_statements": [dev_swamid_sost],
})

print(70 * "-")
print('Developer adds software_statement to the Client Registration request')
print(70 * "-")
コード例 #13
0
# -----------------------------------------------------------------------------
# -- 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
# -----------------------------------------------------------------------------

# adds the developers software statement
rreq.update({
    "software_statements": [dev_swamid_sost],
})

print(70 * "-")
print('Developer adds software_statement to the Client Registration request')