def test_parse_open_id_request(self):
        userinfo_claims = Claims(name={"essential": True}, nickname=None,
                                 email={"essential": True},
                                 email_verified={"essential": True},
                                 picture=None)
        id_token_claims = Claims(auth_time={"essential": True,
                                            "acr": {"values": [
                                                "urn:mace:incommon:iap:silver"]}})
        claims_req = ClaimsRequest(userinfo=userinfo_claims,
                                   id_token=id_token_claims)

        oidreq = OpenIDRequest(response_type=["code", "id_token"],
                               client_id=CLIENT_ID,
                               redirect_uri="https://client.example.com/cb",
                               scope="openid profile", state="n-0S6_WzA2Mj",
                               nonce="af0ifjsldkj", max_age=86400,
                               claims=claims_req)

        request = self.srv.parse_open_id_request(data=oidreq.to_json(),
                                                 sformat="json")
        assert isinstance(request, OpenIDRequest)
        assert _eq(request.keys(), ['nonce', 'claims', 'state', 'redirect_uri',
                                    'response_type', 'client_id', 'scope',
                                    'max_age'])
        assert request["nonce"] == "af0ifjsldkj"
        assert "email" in request["claims"]["userinfo"]
Beispiel #2
0
    def test_parse_open_id_request(self):
        userinfo_claims = Claims(name={"essential": True},
                                 nickname=None,
                                 email={"essential": True},
                                 email_verified={"essential": True},
                                 picture=None)
        id_token_claims = Claims(auth_time={
            "essential": True,
            "acr": {
                "values": ["urn:mace:incommon:iap:silver"]
            }
        })
        claims_req = ClaimsRequest(userinfo=userinfo_claims,
                                   id_token=id_token_claims)

        oidreq = OpenIDRequest(response_type=["code", "id_token"],
                               client_id=CLIENT_ID,
                               redirect_uri="https://client.example.com/cb",
                               scope="openid profile",
                               state="n-0S6_WzA2Mj",
                               nonce="af0ifjsldkj",
                               max_age=86400,
                               claims=claims_req)

        request = self.srv.parse_open_id_request(data=oidreq.to_json(),
                                                 sformat="json")
        assert isinstance(request, OpenIDRequest)
        assert _eq(request.keys(), [
            'nonce', 'claims', 'state', 'redirect_uri', 'response_type',
            'client_id', 'scope', 'max_age'
        ])
        assert request["nonce"] == "af0ifjsldkj"
        assert "email" in request["claims"]["userinfo"]
Beispiel #3
0
def make_openid_request(arq, keys, userinfo_claims=None,
                        idtoken_claims=None, algorithm=OIC_DEF_SIGN_ALG,
                        **kwargs):
    """
    Construct the specification of what I want returned.
    The request will be signed
    """

    oir_args = {}

    if userinfo_claims is not None:
        # UserInfoClaims
        claim = Claims(**userinfo_claims["claims"])

        uic_args = {}
        for prop, val in userinfo_claims.items():
            if prop == "claims":
                continue
            if prop in UserInfoClaim.c_param.keys():
                uic_args[prop] = val

        uic = UserInfoClaim(claims=claim, **uic_args)
    else:
        uic = None

    if uic:
        oir_args["userinfo"] = uic

    if idtoken_claims is not None:
        #IdTokenClaims
        try:
            _max_age = idtoken_claims["max_age"]
        except KeyError:
            _max_age=MAX_AUTHENTICATION_AGE

        id_token = IDTokenClaim(max_age=_max_age)
        if "claims" in idtoken_claims:
            idtclaims = Claims(**idtoken_claims["claims"])
            id_token["claims"] = idtclaims
    else: # uic must be != None
        id_token = IDTokenClaim(max_age=MAX_AUTHENTICATION_AGE)

    if id_token:
        oir_args["id_token"] = id_token

    for prop in OpenIDRequest.c_param.keys():
        try:
            oir_args[prop] = arq[prop]
        except KeyError:
            pass

    for attr in ["scope", "response_type"]:
        if attr in oir_args:
            oir_args[attr] = " ".join(oir_args[attr])

    oir = OpenIDRequest(**oir_args)

    return oir.to_jwt(key=keys, algorithm=algorithm)
Beispiel #4
0
 def _parse_openid_request(self, request, redirect_uri, jwt_key):
     try:
         return OpenIDRequest().from_jwt(request, jwt_key)
     except Exception, err:
         logger.error("Faulty request: %s" % request)
         logger.error("Verfied with JWT_keys: %s" % jwt_key)
         logger.error("Exception: %s" % (err.__class__.__name__,))
         openid_req = OpenIDRequest().from_jwt(request, jwt_key,
                                               verify=False)
         logger.error("Request: %s" % openid_req.to_dict())
         return self._redirect_authz_error("invalid_openid_request_object",
                                           redirect_uri)
Beispiel #5
0
    def test_openid_request_with_request_2(self):
        areq = self.client.construct_OpenIDRequest(idtoken_claims={"claims": {"user_id": {"value": "248289761001"}}})

        print areq
        assert areq
        assert areq.request

        _keys = self.client.keystore.get_keys("ver", owner=None)
        jwtreq = OpenIDRequest().deserialize(areq["request"], "jwt", key=_keys)
        print
        print jwtreq
        print jwtreq.keys()
        assert _eq(jwtreq.keys(), ["id_token", "state", "redirect_uri", "response_type", "client_id"])
Beispiel #6
0
    def _collect_user_info(self, session, userinfo_claims=None):
        """
        Collect information about a user.
        This can happen in two cases, either when constructing an IdToken or
        when returning user info through the UserInfo endpoint

        :param session: Session information
        :param userinfo_claims: user info claims
        :return: User info
        """
        if userinfo_claims is None:
            uic = {}
            for scope in session["scope"]:
                try:
                    claims = dict([(name, None) for name in
                                   SCOPE2CLAIMS[scope]])
                    uic.update(claims)
                except KeyError:
                    pass

            if "oidreq" in session:
                oidreq = OpenIDRequest().deserialize(session["oidreq"], "json")
                logger.debug("OIDREQ: %s" % oidreq.to_dict())
                try:
                    _claims = oidreq["claims"]["userinfo"]
                except KeyError:
                    pass
                else:
                    for key, val in uic.items():
                        if key not in _claims:
                            _claims[key] = val
                    uic = _claims

                if uic:
                    userinfo_claims = Claims(**uic)
                else:
                    userinfo_claims = None
            elif uic:
                userinfo_claims = Claims(**uic)
            else:
                userinfo_claims = None

            logger.debug("userinfo_claim: %s" % userinfo_claims.to_dict())

        logger.debug("Session info: %s" % session)
        info = self.userinfo(session["local_sub"], userinfo_claims)

        info["sub"] = session["sub"]
        logger.debug("user_info_response: %s" % (info,))

        return info
    def test_openid_request_with_id_token_claims_request(self):
        areq = self.client.construct_AuthorizationRequest(
                request_args={"scope": "openid",
                              "response_type": ["code"],
                              "claims": {
                                  "id_token": {"sub": {"value": "248289761001"}}}},
                request_param="request"
        )

        jwtreq = OpenIDRequest().deserialize(areq["request"], "jwt",
                                             keyjar=self.client.keyjar)
        assert _eq(jwtreq.keys(), ['claims',
                                   'redirect_uri', 'response_type',
                                   'client_id', 'scope'])
Beispiel #8
0
    def id_token_claims(session):
        """
        Pick the IdToken claims from the request

        :param session: Session information
        :return: The IdToken claims
        """
        itc = None

        try:
            authzreq = AuthorizationRequest().deserialize(
                session["authzreq"], 'json')
            itc = authzreq["claims"]["id_token"]
            logger.debug("ID Token claims: %s" % itc)
        except KeyError:
            pass

        try:
            oidreq = OpenIDRequest().deserialize(session["oidreq"], "json")
            itc_or = oidreq["claims"]["id_token"]
            if itc:
                itc.update(itc_or)
            logger.debug("ID Token claims: %s" % itc)
        except KeyError:
            pass

        return itc
Beispiel #9
0
    def test_openid_request_with_id_token_claims_request(self):
        areq = self.client.construct_AuthorizationRequest(
            request_args={
                "scope": "openid",
                "response_type": ["code"],
                "claims": {"id_token": {"sub": {"value": "248289761001"}}},
            },
            request_param="request",
        )

        jwtreq = OpenIDRequest().deserialize(
            areq["request"], "jwt", keyjar=self.client.keyjar
        )
        assert _eq(
            jwtreq.keys(),
            ["claims", "redirect_uri", "response_type", "client_id", "scope"],
        )
Beispiel #10
0
    def test_openid_request_with_request_2(self):
        areq = self.client.construct_AuthorizationRequest(
            request_args={"scope":"openid", "response_type":["code"]},
            idtoken_claims={"claims": {"sub": {"value":"248289761001"}}},
        )

        print areq
        assert areq
        assert areq.request

        jwtreq = OpenIDRequest().deserialize(areq["request"], "jwt",
                                             keyjar=self.client.keyjar)
        print
        print jwtreq
        print jwtreq.keys()
        assert _eq(jwtreq.keys(), ['id_token', 'state',
                                   'redirect_uri', 'response_type',
                                   'client_id', 'scope'])
Beispiel #11
0
def make_openid_request(arq,
                        keys=None,
                        userinfo_claims=None,
                        idtoken_claims=None,
                        algorithm=None,
                        **kwargs):
    """
    Construct the specification of what I want returned.
    The request will be signed

    :param arq: The Authorization request
    :param keys: Keys to use for signing/encrypting
    :param userinfo_claims: UserInfo claims
    :param idtoken_claims: IdToken claims
    :param algorithm: Which signing/encrypting algorithm to use
    :return: JWT encoded OpenID request
    """

    oir_args = {}
    for prop in OpenIDRequest.c_param.keys():
        try:
            oir_args[prop] = arq[prop]
        except KeyError:
            pass

    for attr in ["scope", "response_type"]:
        if attr in oir_args:
            oir_args[attr] = " ".join(oir_args[attr])

    c_args = {}
    if userinfo_claims is not None:
        # UserInfoClaims
        c_args["userinfo"] = Claims(**userinfo_claims)

    if idtoken_claims is not None:
        #IdTokenClaims
        c_args["id_token"] = Claims(**idtoken_claims)

    if c_args:
        oir_args["claims"] = ClaimsRequest(**c_args)

    oir = OpenIDRequest(**oir_args)

    return oir.to_jwt(key=keys, algorithm=algorithm)
Beispiel #12
0
def make_openid_request(arq, keys=None, userinfo_claims=None,
                        idtoken_claims=None, algorithm=None,
                        **kwargs):
    """
    Construct the specification of what I want returned.
    The request will be signed

    :param arq: The Authorization request
    :param keys: Keys to use for signing/encrypting
    :param userinfo_claims: UserInfo claims
    :param idtoken_claims: IdToken claims
    :param algorithm: Which signing/encrypting algorithm to use
    :return: JWT encoded OpenID request
    """

    oir_args = {}
    for prop in OpenIDRequest.c_param.keys():
        try:
            oir_args[prop] = arq[prop]
        except KeyError:
            pass

    for attr in ["scope", "response_type"]:
        if attr in oir_args:
            oir_args[attr] = " ".join(oir_args[attr])

    c_args = {}
    if userinfo_claims is not None:
        # UserInfoClaims
        c_args["userinfo"] = Claims(**userinfo_claims)

    if idtoken_claims is not None:
        #IdTokenClaims
        c_args["id_token"] = Claims(**idtoken_claims)

    if c_args:
        oir_args["claims"] = ClaimsRequest(**c_args)

    oir = OpenIDRequest(**oir_args)

    return oir.to_jwt(key=keys, algorithm=algorithm)
Beispiel #13
0
    def update_claims(session, where, about, old_claims=None):
        """

        :param session:
        :param where: Which request
        :param about: userinfo or id_token
        :param old_claims:
        :return: claims or None
        """

        if old_claims is None:
            old_claims = {}

        req = None
        if where == "oidreq":
            try:
                req = OpenIDRequest().deserialize(session[where], "json")
            except KeyError:
                pass
        else:  # where == "authzreq"
            try:
                req = AuthorizationRequest().deserialize(session[where], "json")
            except KeyError:
                pass

        if req:
            logger.debug("%s: %s" % (where, req.to_dict()))
            try:
                _claims = req["claims"][about]
                if _claims:
                    # update with old claims, do not overwrite
                    for key, val in old_claims.items():
                        if key not in _claims:
                            _claims[key] = val
                    return _claims
            except KeyError:
                pass

        return old_claims
Beispiel #14
0
    def id_token_claims(self, session):
        """
        Pick the IdToken claims from the request

        :param session: Session information
        :return: The IdToken claims
        """
        try:
            oidreq = OpenIDRequest().deserialize(session["oidreq"], "json")
            itc = oidreq["claims"]["id_token"]
            logger.debug("ID Token claims: %s" % itc)
            return itc
        except KeyError:
            return None
Beispiel #15
0
    def end_session_endpoint(self, request="", cookie=None, **kwargs):
        areq = None
        redirect_uri = None
        try:
            areq = urlparse.parse_qs(request)
            redirect_uri = self.verify_post_logout_redirect_uri(areq, cookie)
            authn = self.pick_auth(areq)
            identity = authn.authenticated_as(cookie)
            if "uid" not in identity:
                return self._error_response("Not allowed!")
        except:
            return self._error_response("Not allowed!")

        verify = self.sdb.getVerifyLogout(identity["uid"])
        if (verify is None or "key" not in areq or verify != areq["key"][0]) and \
                (self.template_lookup is not None and self.verify_login_template is not None):
            if cookie:
                headers = [cookie]
            else:
                headers = []
            mte = self.template_lookup.get_template(self.verify_login_template)
            self.sdb.setVerifyLogout(identity["uid"])
            if redirect_uri is not None:
                redirect = redirect_uri
            else:
                redirect = "/"
            try:
                tmp_id_token_hint = areq["id_token_hint"][0]
            except:
                tmp_id_token_hint = ""
            argv = {
                "id_token_hint": tmp_id_token_hint,
                "post_logout_redirect_uri": areq["post_logout_redirect_uri"][0],
                "key": self.sdb.getVerifyLogout(identity["uid"]),
                "redirect": redirect,
                "action": "/"+EndSessionEndpoint("").etype
            }
            #resp.message = mte.render(**argv)
            return Response(mte.render(**argv), headers=[])

        id_token = None
        try:
            id_token = self.sdb.getToken_id(identity["uid"])
        except:
            pass

        if id_token is not None and "id_token_hint" in areq:
            try:
                id_token_hint = OpenIDRequest().from_jwt(areq["id_token_hint"][0], keyjar=self.keyjar, verify=True)
                id_token = OpenIDRequest().from_jwt(id_token, keyjar=self.keyjar, verify=True)
                id_token_hint_dict = id_token_hint.to_dict()
                id_token_dict = id_token.to_dict()
                for key in id_token_dict:
                    if key in id_token_hint_dict:
                        if id_token_dict[key] != id_token_hint_dict[key]:
                            return self._error_response("Not allowed!")
                    else:
                        return self._error_response("Not allowed!")
                for key in id_token_hint_dict:
                    if key in id_token_dict:
                        if id_token_dict[key] != id_token_hint_dict[key]:
                            return self._error_response("Not allowed!")
                    else:
                        return self._error_response("Not allowed!")
            except:
                self._error_response("Not allowed!")
        elif id_token is not None:
            self._error_response("Not allowed!")

        try:
            self.sdb.revoke_uid(identity["uid"])
        except:
            pass
            #If cleanup cannot be performed we will still invalidate the cookie.

        if redirect_uri is not None:
            return Redirect(str(redirect_uri), headers=[authn.delete_cookie()])

        return Response("", headers=[authn.delete_cookie()])