コード例 #1
0
def _faulty_id_token():
    idval = {'nonce': 'KUEYfRM2VzKDaaKD', 'sub': 'EndUserSubject',
             'iss': 'https://alpha.cloud.nds.rub.de', 'exp': 1420823073,
             'iat': 1420822473, 'aud': 'TestClient'}
    idts = IdToken(**idval)

    _signed_jwt = idts.to_jwt(key=[SYMKEY], algorithm="HS256")

    # Mess with the signed id_token
    p = _signed_jwt.split(".")
    p[2] = "aaa"

    return ".".join(p)
コード例 #2
0
ファイル: test_oic_message.py プロジェクト: joostd/pyoidc
    def test_wrong_alg(self):
        idval = {'nonce': 'KUEYfRM2VzKDaaKD', 'sub': 'EndUserSubject',
                 'iss': 'https://alpha.cloud.nds.rub.de', 'exp': 1420823073,
                 'iat': 1420822473, 'aud': 'TestClient'}
        idts = IdToken(**idval)
        key = SYMKey(key="TestPassword")
        _signed_jwt = idts.to_jwt(key=[key], algorithm="HS256")

        _info = {"access_token": "accessTok", "id_token": _signed_jwt,
                 "token_type": "Bearer", "expires_in": 3600}

        at = AccessTokenResponse(**_info)
        with pytest.raises(WrongSigningAlgorithm):
            at.verify(key=[key], algs={"sign": "HS512"})
コード例 #3
0
    def test_logout(self):
        end_session_endpoint = 'https://provider.example.com/end_session'
        post_logout_uri = 'https://client.example.com/post_logout'
        authn = OIDCAuthentication(self.app,
                                   provider_configuration_info={'issuer': ISSUER,
                                                                'end_session_endpoint': end_session_endpoint},
                                   client_registration_info={'client_id': 'foo',
                                                             'post_logout_redirect_uris': [post_logout_uri]})
        id_token = IdToken(**{'sub': 'sub1', 'nonce': 'nonce'})
        with self.app.test_request_context('/logout'):
            flask.session['access_token'] = 'abcde'
            flask.session['userinfo'] = {'foo': 'bar', 'abc': 'xyz'}
            flask.session['id_token'] = id_token.to_dict()
            flask.session['id_token_jwt'] = id_token.to_jwt()
            end_session_redirect = authn._logout()

            assert all(k not in flask.session for k in ['access_token', 'userinfo', 'id_token', 'id_token_jwt'])

            assert end_session_redirect.status_code == 303
            assert end_session_redirect.headers['Location'].startswith(end_session_endpoint)
            parsed_request = dict(parse_qsl(urlparse(end_session_redirect.headers['Location']).query))
            assert parsed_request['state'] == flask.session['end_session_state']
            assert parsed_request['id_token_hint'] == id_token.to_jwt()
            assert parsed_request['post_logout_redirect_uri'] == post_logout_uri
コード例 #4
0
 def test_oidc_logout_redirects_to_provider(self):
     end_session_endpoint = 'https://provider.example.com/end_session'
     post_logout_uri = 'https://client.example.com/post_logout'
     authn = OIDCAuthentication(self.app,
                                provider_configuration_info={'issuer': ISSUER,
                                                             'end_session_endpoint': end_session_endpoint},
                                client_registration_info={'client_id': 'foo',
                                                          'post_logout_redirect_uris': [post_logout_uri]})
     callback_mock = MagicMock()
     callback_mock.__name__ = 'test_callback'  # required for Python 2
     id_token = IdToken(**{'sub': 'sub1', 'nonce': 'nonce'})
     with self.app.test_request_context('/logout'):
         flask.session['id_token_jwt'] = id_token.to_jwt()
         resp = authn.oidc_logout(callback_mock)()
     assert resp.status_code == 303
     assert not callback_mock.called
コード例 #5
0
    def test_logout_handles_provider_without_end_session_endpoint(self):
        post_logout_uri = 'https://client.example.com/post_logout'
        authn = OIDCAuthentication(self.app,
                                   provider_configuration_info={'issuer': ISSUER},
                                   client_registration_info={'client_id': 'foo',
                                                             'post_logout_redirect_uris': [post_logout_uri]})
        id_token = IdToken(**{'sub': 'sub1', 'nonce': 'nonce'})
        with self.app.test_request_context('/logout'):
            flask.session['access_token'] = 'abcde'
            flask.session['userinfo'] = {'foo': 'bar', 'abc': 'xyz'}
            flask.session['id_token'] = id_token.to_dict()
            flask.session['id_token_jwt'] = id_token.to_jwt()
            end_session_redirect = authn._logout()

            assert all(k not in flask.session for k in ['access_token', 'userinfo', 'id_token', 'id_token_jwt'])
            assert end_session_redirect is None
コード例 #6
0
ファイル: test_oic_message.py プロジェクト: joostd/pyoidc
    def test_faulty_idtoken(self):
        idval = {'nonce': 'KUEYfRM2VzKDaaKD', 'sub': 'EndUserSubject',
                 'iss': 'https://alpha.cloud.nds.rub.de', 'exp': 1420823073,
                 'iat': 1420822473, 'aud': 'TestClient'}
        idts = IdToken(**idval)
        key = SYMKey(key="TestPassword")
        _signed_jwt = idts.to_jwt(key=[key], algorithm="HS256")

        # Mess with the signed id_token
        p = _signed_jwt.split(".")
        p[2] = "aaa"
        _faulty_signed_jwt = ".".join(p)

        _info = {"access_token": "accessTok", "id_token": _faulty_signed_jwt,
                 "token_type": "Bearer", "expires_in": 3600}

        at = AccessTokenResponse(**_info)
        with pytest.raises(BadSignature):
            at.verify(key=[key])
コード例 #7
0
ファイル: debug_keyio_local.py プロジェクト: asheidan/pyoidc
from jwkest.jws import alg2keytype
from oic.oic.message import IdToken
from oic.utils.keyio import KeyBundle, KeyJar

__author__ = 'rohe0002'

b0 = KeyBundle(source="http://localhost:8090/exports/jwk.json", src_type="jwk",
               usage=["ver", "dec", "sig"])

b1 = KeyBundle(source="http://localhost:8090/exports/cert.pem", src_type="x509",
               usage=["ver", "dec", "sig"])

print b0
print b1

kj = KeyJar()

kj["foobar"] = [b0, b1]

idt = IdToken().from_dict({"user_id": "diana", "aud": "uo5nowsdL3ck",
                           "iss": "https://localhost:8092", "acr": "2",
                           "exp": 1354442188, "iat": 1354359388})

ckey = kj.get_signing_key(alg2keytype("RS256"), "foobar")
_signed_jwt = idt.to_jwt(key=ckey, algorithm="RS256")
コード例 #8
0
ファイル: test_oic.py プロジェクト: dash-dash/pyoidc
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"))

ESREQ = EndSessionRequest(id_token=IDTOKEN.to_jwt(key=keys,
                                                  algorithm="HS256"),
                          redirect_url="http://example.org/jqauthz",
                          state="state0")

UINFO = Claims(name={"essential": True}, nickname=None,
               email={"essential": True},
               email_verified={"essential": True}, picture=None)

IDT2 = Claims(auth_time={"essential": True,
                         "acr": {"values": ["urn:mace:incommon:iap:silver"]}})

CLAIMS = ClaimsRequest(userinfo=UINFO, id_token=IDT2)
コード例 #9
0
ファイル: test_oic.py プロジェクト: imsoftware/pyoidc
UIREQ = UserInfoRequest(access_token="access_token", schema="openid")

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

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

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

CSREQ = CheckSessionRequest(id_token=IDTOKEN.to_jwt(key=SIGN_KEY))

ESREQ = EndSessionRequest(
    id_token=IDTOKEN.to_jwt(key=SIGN_KEY), redirect_url="http://example.org/jqauthz", state="state0"
)

IDT2 = IDTokenClaim(max_age=86400)

CLAIM = Claims(
    name={"essential": True}, nickname=None, email={"essential": True}, email_verified={"essential": True}, picture=None
)

USRINFO = UserInfoClaim(claims=CLAIM, format="signed")

OIDREQ = OpenIDRequest(
    response_type=["code", "id_token"],
コード例 #10
0
    def test_complete_auth_token_idtoken(self):
        _state = "state0"
        self.consumer.consumer_config["response_type"] = ["id_token", "token"]
        self.consumer.registration_response = {"id_token_signed_response_alg": "RS256"}
        self.consumer.provider_info = {"issuer": "https://example.com"}  # abs min
        self.consumer.authz_req = {}  # Store AuthzReq with state as key

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

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

        with freeze_time("2019-08-09 11:00:00"):
            part = self.consumer.parse_authz(
                query=parsed.query, algs=self.consumer.sign_enc_algs("id_token")
            )
        auth = part[0]
        atr = part[1]
        assert part[2] is None

        assert auth is None
        assert isinstance(atr, AccessTokenResponse)
        assert _eq(
            atr.keys(), ["access_token", "id_token", "token_type", "state", "scope"]
        )

        with freeze_time("2019-08-09 11:00:00"):
            self.consumer.verify_id_token(
                atr["id_token"], self.consumer.authz_req[atr["state"]]
            )
コード例 #11
0
ファイル: test_oic.py プロジェクト: minhoryang/pyoidc
                             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"))

ESREQ = EndSessionRequest(id_token=IDTOKEN.to_jwt(key=keys, algorithm="HS256"),
                          redirect_url="http://example.org/jqauthz",
                          state="state0")

UINFO = Claims(name={"essential": True},
               nickname=None,
               email={"essential": True},
               email_verified={"essential": True},
               picture=None)

IDT2 = Claims(auth_time={
    "essential": True,
    "acr": {
        "values": ["urn:mace:incommon:iap:silver"]
コード例 #12
0
ファイル: test_oic.py プロジェクト: asheidan/pyoidc
                            scope=["openid"], state="state0", nonce="N0nce")

UIREQ = UserInfoRequest(access_token="access_token", schema="openid")

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="."

CSREQ = CheckSessionRequest(id_token=IDTOKEN.to_jwt(key=KC_HMAC_S))

ESREQ = EndSessionRequest(id_token=IDTOKEN.to_jwt(key=KC_HMAC_S),
                          redirect_url="http://example.org/jqauthz",
                          state="state0")

IDT2 = IDTokenClaim(max_age=86400)

CLAIM = Claims(name={"essential": True}, nickname=None,
               email={"essential": True},
               email_verified={"essential": True}, picture=None)

USRINFO = UserInfoClaim(claims=CLAIM, sformat="signed")

OIDREQ = OpenIDRequest(response_type=["code", "id_token"], client_id=CLIENT_ID,
                       redirect_uri="https://client.example.com/cb",
コード例 #13
0
    def __call__(self, request):
        data = request.body

        req = self.provider.parse_token_request(body=data)

        if 'grant_type' not in req:
            return (400, {}, 'Missing grant_type')

        if req['grant_type'] == 'authorization_code':
            authz_code = req['code']
            authz_info = self.provider.authz_codes[authz_code]
            auth_req = authz_info['auth_req']
            client_id = auth_req['client_id']

            if authz_info['used']:
                raise Exception('code already used')
                return (400, {}, 'Invalid authorization code')

            if authz_info['exp'] < time.time():
                raise Exception('code expired')
                return (400, {}, 'Invalid authorization code')

            authz_info['used'] = True

            access_token = {
                'value': rndstr(),
                'expires_in': self.provider.access_token_lifetime,
                'type': 'Bearer'
            }

            at_value = access_token['value']

            self.provider.access_tokens[at_value] = {
                'iat': time.time(),
                'exp': time.time() + self.provider.access_token_lifetime,
                'sub': 'test-sub',
                'client_id': client_id,
                'aud': [client_id],
                'scope': authz_info['granted_scope'],
                'granted_scope': authz_info['granted_scope'],
                'token_type': access_token['type'],
                'auth_req': auth_req
            }

            resp = AccessTokenResponse()
            resp['access_token'] = at_value
            resp['token_type'] = access_token['type']
            resp['expires_in'] = access_token['expires_in']

            resp['refresh_token'] = None

            args = {
                'c_hash': jws.left_hash(authz_code.encode('utf-8'), 'HS256'),
                'at_hash': jws.left_hash(at_value.encode('utf-8'), 'HS256'),
            }

            id_token = IdToken(iss=self.config['issuer'],
                               sub='test-sub',
                               aud=client_id,
                               iat=time.time(),
                               exp=time.time() +
                               self.provider.id_token_lifetime,
                               **args)

            if 'nonce' in auth_req:
                id_token['nonce'] = auth_req['nonce']

            resp['id_token'] = id_token.to_jwt([self.provider.signing_key],
                                               'RS256')

            json_data = resp.to_json()

            return (200, {
                'Content-Type': 'application/json',
                'Cache-Control': 'no-store',
                'Pragma': 'no-cache',
            }, json_data)

        return (400, {}, 'Unsupported grant_type')
コード例 #14
0
ファイル: __init__.py プロジェクト: imsoftware/pyoidc
    def make_id_token(self, session, loa="2", issuer="",
                      keytype="rsa", code=None, access_token=None,
                      user_info=None):
        #defaults
        inawhile = {"days": 1}
        # Handle the idtoken_claims
        extra = {}
        try:
            oidreq = OpenIDRequest().deserialize(session["oidreq"], "json")
            itc = oidreq["id_token"]
            logger.debug("ID Token claims: %s" % itc.to_dict())
            try:
                inawhile = {"seconds": itc["max_age"]}
            except KeyError:
                inawhile = {}
            if "claims" in itc:
                for key, val in itc["claims"].items():
                    if key == "auth_time":
                        extra["auth_time"] = time_util.utc_time_sans_frac()
                    elif key == "acr":
                        #["2","http://id.incommon.org/assurance/bronze"]
                        extra["acr"] = verify_acr_level(val, loa)
        except KeyError:
            pass

        if user_info is None:
            _args = {}
        else:
            _args = user_info.to_dict()

        # Make sure that there are no name clashes
        for key in ["iss", "user_id", "aud", "exp", "acr", "nonce",
                    "auth_time"]:
            try:
                del _args[key]
            except KeyError:
                pass

        if code:
            _args["c_hash"] = jwt.left_hash(code, "HS256")
        if access_token:
            _args["at_hash"] = jwt.left_hash(access_token, "HS256")

        idt = IdToken(iss=issuer, user_id=session["user_id"],
                      aud = session["client_id"],
                      exp = time_util.epoch_in_a_while(**inawhile), acr=loa,
                      **_args)

        for key, val in extra.items():
            idt[key] = val

        if "nonce" in session:
            idt.nonce = session["nonce"]

        # sign with clients secret key
        _keystore = self.keystore
        if keytype == "hmac":
            ckey = {"hmac":
                        _keystore.get_sign_key("hmac",
                                               owner=session["client_id"])}
            algo = "HS256"
        elif keytype == "rsa": # own asymmetric key
            algo = "RS256"
            ckey = {"rsa": _keystore.get_sign_key("rsa")}
        else:
            algo = "ES256"
            ckey = {"ec":_keystore.get_sign_key("ec")}

        logger.debug("Sign idtoken with '%s'" % (ckey,))

        return idt.to_jwt(key=ckey, algorithm=algo)
コード例 #15
0
ファイル: test_oic_consumer.py プロジェクト: smkent/pyoidc
    def test_complete_auth_token_idtoken_none_cipher_code(self):
        _state = "state0"
        self.consumer.consumer_config["response_type"] = ["code"]
        self.consumer.registration_response = RegistrationResponse(
            id_token_signed_response_alg="none")
        self.consumer.provider_info = ProviderConfigurationResponse(
            issuer="https://example.com")  # abs min
        self.consumer.authz_req = {}  # Store AuthzReq with state as key
        self.consumer.sdb[_state] = {"redirect_uris": []}

        args = {
            "client_id": self.consumer.client_id,
            "response_type": self.consumer.consumer_config["response_type"],
            "scope": ["openid"],
            "nonce": "nonce",
        }
        token = IdToken(
            iss="https://example.com",
            aud="client_1",
            sub="some_sub",
            exp=1565348600,
            iat=1565348300,
            nonce="nonce",
            at_hash="aaa",
        )
        # Downgrade the algorithm to `none`
        location = (
            "https://example.com/cb?state=state0&access_token=token&token_type=bearer&"
            "scope=openid&id_token={}".format(
                token.to_jwt(key=KC_RSA.keys(), algorithm="none")))
        with responses.RequestsMock() as rsps:
            rsps.add(
                responses.GET,
                "https://example.com/authorization",
                status=302,
                headers={"location": location},
            )
            result = self.consumer.do_authorization_request(state=_state,
                                                            request_args=args)
            query = parse_qs(urlparse(result.request.url).query)
            assert query["client_id"] == ["client_1"]
            assert query["scope"] == ["openid"]
            assert query["response_type"] == ["code"]
            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 isinstance(auth, AuthorizationResponse)
        assert isinstance(atr, AccessTokenResponse)
        assert _eq(
            atr.keys(),
            ["access_token", "id_token", "token_type", "state", "scope"])
        assert isinstance(idt, IdToken)
コード例 #16
0
    def __call__(self, request):
        data = request.body

        req = self.provider.parse_token_request(body=data)

        if 'grant_type' not in req:
            return (400, {}, 'Missing grant_type')

        if req['grant_type'] == 'authorization_code':
            authz_code = req['code']
            authz_info = self.provider.authz_codes[authz_code]
            auth_req = authz_info['auth_req']
            client_id = auth_req['client_id']

            if authz_info['used']:
                raise Exception('code already used')
                return (400, {}, 'Invalid authorization code')

            if authz_info['exp'] < time.time():
                raise Exception('code expired')
                return (400, {}, 'Invalid authorization code')

            authz_info['used'] = True

            access_token = {
                'value': rndstr(),
                'expires_in': self.provider.access_token_lifetime,
                'type': 'Bearer'
            }

            at_value = access_token['value']

            self.provider.access_tokens[at_value] = {
                'iat': time.time(),
                'exp': time.time() + self.provider.access_token_lifetime,
                'sub': 'test-sub',
                'client_id': client_id,
                'aud': [client_id],
                'scope': authz_info['granted_scope'],
                'granted_scope': authz_info['granted_scope'],
                'token_type': access_token['type'],
                'auth_req': auth_req
            }

            resp = AccessTokenResponse()
            resp['access_token'] = at_value
            resp['token_type'] = access_token['type']
            resp['expires_in'] = access_token['expires_in']

            resp['refresh_token'] = None

            args = {
                'c_hash': jws.left_hash(authz_code.encode('utf-8'), 'HS256'),
                'at_hash': jws.left_hash(at_value.encode('utf-8'), 'HS256'),
            }

            id_token = IdToken(
                iss=self.config['issuer'],
                sub='test-sub',
                aud=client_id,
                iat=time.time(),
                exp=time.time() + self.provider.id_token_lifetime,
                **args)

            if 'nonce' in auth_req:
                id_token['nonce'] = auth_req['nonce']

            resp['id_token'] = id_token.to_jwt(
                [self.provider.signing_key], 'RS256')

            json_data = resp.to_json()

            return (
                200,
                {
                    'Content-Type': 'application/json',
                    'Cache-Control': 'no-store',
                    'Pragma': 'no-cache',
                },
                json_data
            )

        return (400, {}, 'Unsupported grant_type')