Exemple #1
0
def callback(request):

    response = OrderedDict()
    if 'error' in request.GET:
        return render(request, "access-denied.html", {"error": request.GET.get("error")})
    oas = OAuth2Session(request.session['client_id'],
                        redirect_uri=request.session['redirect_uri'])
    host = settings.HOSTNAME_URL
    if not(host.startswith("http://") or host.startswith("https://")):
        host = "https://%s" % (host)
    auth_uri = host + request.get_full_path()
    token_uri = host + reverse('oauth2_provider:token')
    try:
        token = oas.fetch_token(token_uri,
                                client_secret=get_client_secret(),
                                authorization_response=auth_uri)
    except MissingTokenError:
        logmsg = "Failed to get token from %s" % (request.session['token_uri'])
        logger.error(logmsg)
        return JsonResponse({'error': 'Failed to get token from',
                             'code': 'MissingTokenError',
                             'help': 'Try authorizing again.'}, status=500)
    request.session['token'] = token
    response['token_response'] = OrderedDict()

    for k, v in token.items():
        if k != "scope":
            response['token_response'][k] = v
        else:
            response['token_response'][k] = ' '.join(v)
    response['test_page'] = host + reverse('testclient_home')
    parsed_id_token = JWT().unpack(response['token_response']['id_token'])
    parsed_id_token = parsed_id_token.payload()
    response['id_token_payload'] = parsed_id_token
    return success(request, response)
Exemple #2
0
 def test_construct(self, client):
     _key = rsa_load(os.path.join(BASE_PATH, "data/keys/rsa.key"))
     kc_rsa = KeyBundle([{
         "key": _key,
         "kty": "RSA",
         "use": "ver"
     }, {
         "key": _key,
         "kty": "RSA",
         "use": "sig"
     }])
     client.keyjar[""] = kc_rsa
     client.token_endpoint = "https://example.com/token"
     client.provider_info = {
         'issuer': 'https://example.com/',
         'token_endpoint': "https://example.com/token"
     }
     cis = AccessTokenRequest()
     pkj = PrivateKeyJWT(client)
     http_args = pkj.construct(cis,
                               algorithm="RS256",
                               authn_endpoint='token')
     assert http_args == {}
     cas = cis["client_assertion"]
     _jwt = JWT().unpack(cas)
     jso = _jwt.payload()
     assert _eq(jso.keys(), ["aud", "iss", "sub", "jti", "exp", "iat"])
     assert _jwt.headers == {'alg': 'RS256'}
     assert jso['aud'] == [client.provider_info['token_endpoint']]
Exemple #3
0
    def test_client_secret_jwt(self, client):
        client.token_endpoint = "https://example.com/token"
        client.provider_info = {
            'issuer': 'https://example.com/',
            'token_endpoint': "https://example.com/token"
        }

        csj = ClientSecretJWT(client)
        cis = AccessTokenRequest()

        csj.construct(cis, algorithm="HS256", authn_endpoint='userinfo')
        assert cis["client_assertion_type"] == JWT_BEARER
        assert "client_assertion" in cis
        cas = cis["client_assertion"]
        _jwt = JWT().unpack(cas)
        jso = _jwt.payload()
        assert _eq(jso.keys(), ["aud", "iss", "sub", "jti", "exp", "iat"])
        assert _jwt.headers == {'alg': 'HS256'}

        _rj = JWS()
        info = _rj.verify_compact(
            cas, [SYMKey(k=b64e(as_bytes(client.client_secret)))])

        assert _eq(info.keys(), ["aud", "iss", "sub", "jti", "exp", "iat"])
        assert info['aud'] == [client.provider_info['issuer']]
Exemple #4
0
    def wrapper(request, *args, **kwargs):

        if request.user.is_authenticated:
            try:
                vmi = request.user.social_auth.filter(
                    provider='verifymyidentity-openidconnect')[0]
                extra_data = vmi.extra_data
                if 'id_token' in vmi.extra_data.keys():
                    id_token = extra_data.get('id_token')
                    parsed_id_token = JWT().unpack(id_token)
                    parsed_id_token = parsed_id_token.payload()
            except Exception:
                id_token = "No ID token."
                parsed_id_token = {
                    'sub': '',
                    'ial': '1',
                    "note": "No ID token for this user"
                }
            if parsed_id_token['ial'] not in ('2', '3'):
                msg = _(
                    "%s %s was defined access due to insufficient identity assurance  level (IAL). Subject=%s"
                    "" % (request.user.first_name, request.user.last_name,
                          parsed_id_token['sub']))
                logger.info(msg)
                response_string = _(
                    """Your identity assurance level (IAL) of 1 is insufficient for this action."""
                )
                return HttpResponseForbidden(response_string)

        return func(request, *args, **kwargs)
Exemple #5
0
def create_or_update_org(backend, user, response, *args, **kwargs):
    if backend.name == 'verifymyidentity-openidconnect':
        if 'id_token' in response.keys():
            id_token = response.get('id_token')
            parsed_id_token = JWT().unpack(id_token)
            payload = parsed_id_token.payload()
            org_slugs = []
            if 'organization_agent' in payload:
                for organization in payload['organization_agent']:
                    org, g_o_c = Organization.objects.get_or_create(
                        slug=organization['slug'])
                    org_slugs.append(organization['slug'])
                    org.name = organization['name']
                    org.sub = organization['sub']
                    org.website = organization['website']
                    org.phone = organization['phone_number']
                    org.picture_url = organization.get('picture', None)
                    org.agents.add(user)  # Make sure the user is an org agent.
                    org.save()

        # remove an agent from organization if they have been removed.
        all_orgs = Organization.objects.all()
        for o in all_orgs:
            if o.slug not in org_slugs:
                o.agents.remove(user)
                o.save()
Exemple #6
0
def test_unpack_str():
    _jwt = JWT(**{"alg": "none"})
    payload = {"iss": "joe", "exp": 1300819380,
               "http://example.com/is_root": True}
    jwt = _jwt.pack(parts=[payload, ""])

    _jwt2 = JWT().unpack(jwt)
    assert _jwt2
    out_payload = _jwt2.payload()
Exemple #7
0
def get_username(strategy, details, backend, user, response, *args, **kwargs):
    # The subject id is the username.
    if backend.name == 'verifymyidentity-openidconnect':
        if 'id_token' in response.keys():
            id_token = response.get('id_token')
            parsed_id_token = JWT().unpack(id_token)
            payload = parsed_id_token.payload()
            return {'username': payload['sub']}
    return
Exemple #8
0
def test_unpack_str():
    _jwt = JWT(**{"alg": "none"})
    payload = {"iss": "joe", "exp": 1300819380,
               "http://example.com/is_root": True}
    jwt = _jwt.pack(parts=[payload, ""])

    _jwt2 = JWT().unpack(jwt)
    assert _jwt2
    out_payload = _jwt2.payload()
Exemple #9
0
def save_profile(backend, user, response, *args, **kwargs):
    if backend.name == 'verifymyidentity-openidconnect':

        profile, g_o_c = UserProfile.objects.get_or_create(user=user)

        if 'id_token' in response.keys():
            id_token = response.get('id_token')
            parsed_id_token = JWT().unpack(id_token)
            payload = parsed_id_token.payload()
            if 'given_name' in payload:
                profile.user.first_name = payload['given_name']

            if 'family_name' in payload:
                profile.user.last_name = payload['family_name']

            if 'sub' in payload:
                profile.subject = payload['sub']

            if 'nickname' in payload:
                profile.nickname = payload['nickname']

            if 'phone_number' in payload:
                profile.mobile_phone_number = payload['phone_number']

            if 'birthdate' in payload:
                if payload['birthdate'] not in ("None", ""):
                    profile.birth_date = payload['birthdate']

            if 'gender' in payload:
                profile.gender = payload['gender']

            if 'email_verified' in payload:
                profile.email_verified = payload['email_verified']

            if 'gender_identity' in payload:
                profile.gender_identity = payload['gender_identity']

            if 'middle_name' in payload:
                profile.middle_name = payload['middle_name']

            if 'phone_verified' in payload:
                profile.phone_verified = payload['phone_verified']

            if 'ial' in payload:
                profile.identity_assurance_level = payload['ial']

            if ('picture' in payload and 'None' not in payload['picture']
                    and 'no-img' not in payload['picture']):
                profile.picture_url = payload['picture']

            profile.most_recent_id_token_payload = json.dumps(payload,
                                                              indent=4)

        profile.user.save()
        profile.save()
Exemple #10
0
def jwt_payload(request):
    if 'jwt' not in request.GET:
        return JsonResponse({"error": "you just supply a jwt as a GET parmeter."})
    myjwt = request.GET.get("jwt")

    try:
        parsed_id_token = JWT().unpack(myjwt)
        parsed_id_token = parsed_id_token.payload()
    except Exception:
        parsed_id_token = {
            "error": "you just supply a valid jwt as a GET parmeter."}
    return JsonResponse(parsed_id_token)
 def unpack_jwt(jwt: str, keys: list):
     """
     Unpacks a signed jwt question
     :type keys: list[str]
     :rtype: dict[str, str]
     :param jwt: A signed jwt containing the question (the idp, id and redirect_endpoint)
     :param keys: A list of keys to use when verifying the signature
     :return: The unpacked jwt
     """
     JWTHandler._verify_jwt(jwt, keys)
     _jwt = JWT().unpack(jwt)
     jso = _jwt.payload()
     if "sp" not in jso or "idp" not in jso or "ticket" not in jso:
         return None
     return jso
 def unpack_jwt(jwt: str, keys: list):
     """
     Unpacks a signed jwt question
     :type keys: list[str]
     :rtype: dict[str, str]
     :param jwt: A signed jwt containing the question (the idp, id and redirect_endpoint)
     :param keys: A list of keys to use when verifying the signature
     :return: The unpacked jwt
     """
     JWTHandler._verify_jwt(jwt, keys)
     _jwt = JWT().unpack(jwt)
     jso = _jwt.payload()
     if "sp" not in jso or "idp" not in jso or "ticket" not in jso:
         return None
     return jso
Exemple #13
0
def test_pack_unpack():
    _jwt = JWT(**{"alg": "none"})
    payload = {"iss": "joe", "exp": 1300819380,
               "http://example.com/is_root": True}
    jwt = _jwt.pack(parts=[payload, ""])

    _jwt2 = JWT().unpack(jwt)

    assert _jwt2
    out_payload = _jwt2.payload()
    assert _eq(out_payload.keys(), ["iss", "exp", "http://example.com/is_root"])
    assert out_payload["iss"] == payload["iss"]
    assert out_payload["exp"] == payload["exp"]
    assert out_payload["http://example.com/is_root"] == payload[
        "http://example.com/is_root"]
Exemple #14
0
def test_pack_unpack():
    _jwt = JWT(**{"alg": "none"})
    payload = {"iss": "joe", "exp": 1300819380,
               "http://example.com/is_root": True}
    jwt = _jwt.pack(parts=[payload, ""])

    _jwt2 = JWT().unpack(jwt)

    assert _jwt2
    out_payload = _jwt2.payload()
    assert _eq(out_payload.keys(), ["iss", "exp", "http://example.com/is_root"])
    assert out_payload["iss"] == payload["iss"]
    assert out_payload["exp"] == payload["exp"]
    assert out_payload["http://example.com/is_root"] == payload[
        "http://example.com/is_root"]
Exemple #15
0
def authenticated_home(request):
    name = _('Authenticated Home')
    if request.user.is_authenticated:

        # Get the ID Token and parse it.
        try:
            vmi = request.user.social_auth.filter(
                provider='verifymyidentity-openidconnect')[0]
            extra_data = vmi.extra_data
            if 'id_token' in vmi.extra_data.keys():
                id_token = extra_data.get('id_token')
                parsed_id_token = JWT().unpack(id_token)
                parsed_id_token = parsed_id_token.payload()

        except Exception:
            id_token = "No ID token."
            parsed_id_token = {'sub': '', 'ial': '1'}

        hp, g_o_c = HIEProfile.objects.get_or_create(user=request.user)

        if parsed_id_token.get('ial') not in ('2', '3'):
            # redirect to get verified
            messages.warning(
                request, 'Your identity has not been verified. \
                             This must be completed prior to access to personal health information.'
            )

        try:
            profile = request.user.userprofile
        except Exception:
            profile = None

        # this is a GET
        context = {
            'name': name,
            'profile': profile,
            'hp': hp,
            'id_token': id_token,
            'id_token_payload': parsed_id_token
        }

        template = 'authenticated-home.html'
    else:
        name = ('home')
        context = {'name': name}
        template = 'index.html'

    return render(request, template, context)
Exemple #16
0
def get_id_token_payload(user):
    # Get the ID Token and parse it.
    try:
        vmi = user.social_auth.filter(provider='vmi')[0]
        extra_data = vmi.extra_data
        if 'id_token' in vmi.extra_data.keys():
            id_token = extra_data.get('id_token')
            parsed_id_token = JWT().unpack(id_token)
            parsed_id_token = parsed_id_token.payload()
        else:
            parsed_id_token = {'sub': '', 'ial': '1'}

    except Exception:
        parsed_id_token = {'sub': '', 'ial': '1'}

    return parsed_id_token
Exemple #17
0
def set_user_type(backend, user, response, *args, **kwargs):

    user_type = "M"
    up, g_o_c = UserProfile.objects.get_or_create(user=user)
    if backend.name == 'vmi':
        user_type = "M"
        up, g_o_c = UserProfile.objects.get_or_create(user=user)
        if 'id_token' in response.keys():
            id_token = response.get('id_token')
            parsed_id_token = JWT().unpack(id_token)
            payload = parsed_id_token.payload()
            if 'organization_agent' in payload:
                if len(payload['organization_agent']) > 0:
                    user_type = "O"
    up.user_type = user_type
    up.save()
Exemple #18
0
    def test_construct(self, client):
        _key = rsa_load(
            os.path.join(BASE_PATH, "data/keys/rsa.key"))
        kc_rsa = KeyBundle([{"key": _key, "kty": "RSA", "use": "ver"},
                            {"key": _key, "kty": "RSA", "use": "sig"}])
        client.keyjar[""] = kc_rsa
        client.token_endpoint = "https://example.com/token"

        cis = AccessTokenRequest()
        pkj = PrivateKeyJWT(client)
        http_args = pkj.construct(cis, algorithm="RS256")
        assert http_args == {}
        cas = cis["client_assertion"]
        _jwt = JWT().unpack(cas)
        jso = _jwt.payload()
        assert _eq(jso.keys(), ["aud", "iss", "sub", "jti", "exp", "iat"])
        assert _jwt.headers == {'alg': 'RS256'}
Exemple #19
0
def id_token_payload_json(request):

    try:
        vmi = request.user.social_auth.filter(
            provider='verifymyidentity-openidconnect')[0]
        extra_data = vmi.extra_data
        if 'id_token' in vmi.extra_data.keys():
            id_token = extra_data.get('id_token')
            parsed_id_token = JWT().unpack(id_token)
            parsed_id_token = parsed_id_token.payload()
    except Exception:
        id_token = "No ID token."
        parsed_id_token = {
            'sub': '',
            'ial': '1',
            "note": "No ID token for this user"
        }
    return JsonResponse(parsed_id_token)
Exemple #20
0
    def test_construct_authz_req_with_request_object(self, tmpdir):
        path = tmpdir.strpath
        request_uri_args = {"local_dir": path, "base_path": "http://example.com/"}
        areq = self.client.construct_AuthorizationRequest(
            request_method="file", **request_uri_args
        )
        p = urlparse(areq["request_uri"])
        local_path = os.path.join(path, p.path.lstrip("/"))
        with open(local_path) as f:
            data = f.read()
        jwt = JWT().unpack(data)
        payload = jwt.payload()

        assert payload["redirect_uri"] == "https://example.com/redirect"
        assert payload["client_id"] == CLIENT_ID
        assert "nonce" in payload

        os.remove(local_path)
Exemple #21
0
def authenticated_home(request):
    name = _('Authenticated Home')
    if request.user.is_authenticated:
        # Get the ID Token and parse it.
        try:
            vmi = request.user.social_auth.filter(
                provider='verifymyidentity-openidconnect')[0]
            extra_data = vmi.extra_data
            if 'id_token' in vmi.extra_data.keys():
                id_token = extra_data.get('id_token')
                parsed_id_token = JWT().unpack(id_token)
                parsed_id_token = parsed_id_token.payload()

        except Exception:
            id_token = "No ID token."
            parsed_id_token = {'sub': '', 'ial': '1'}

        if parsed_id_token.get('ial') not in ('2', '3'):
            # redirect to get verified
            messages.warning(
                request, 'Your identity has not been verified. \
                             This must be completed prior to access to Personal Health Information.'
            )
        try:
            profile = request.user.userprofile
        except Exception:
            profile = None

        # this is a GET
        context = {
            'name': name,
            'profile': profile,
            'id_token': id_token,
            'id_token_payload': parsed_id_token
        }

        template = settings.HOMEPAGE_AUTHENTICATED_TEMPLATE
    else:
        name = ('home')
        context = {'name': name}
        template = settings.HOMEPAGE_TEMPLATE

    return render(request, template, context)
Exemple #22
0
def save_profile(backend, user, response, *args, **kwargs):
    if backend.name == 'vmi':

        profile, g_o_c = UserProfile.objects.get_or_create(user=user)

        if 'id_token' in response.keys():
            id_token = response.get('id_token')
            parsed_id_token = JWT().unpack(id_token)
            payload = parsed_id_token.payload()
            if 'sub' in payload:
                profile.subject = payload['sub']

            if 'nickname' in payload:
                profile.nicname = payload['nickname']

            if 'phone_number' in payload:
                profile.mobile_phone_number = payload['phone_number']

            if 'birthdate' in payload:
                if payload['birthdate'] not in ("None", ""):
                    profile.birth_date = payload['birthdate']

            if 'gender' in payload:
                profile.gender = payload['gender']

            if 'email_verified' in payload:
                profile.email_verified = payload['email_verified']

            if 'phone_verified' in payload:
                profile.phone_verified = payload['phone_verified']

            if 'ial' in payload:
                profile.identity_assurance_level = payload['ial']

            if 'picture' in payload:
                profile.picture_url = payload['picture']
            else:
                profile.picture_url = ''

            profile.most_recent_id_token_payload = json.dumps(
                payload, indent=4)

        profile.save()
Exemple #23
0
    def test_client_secret_jwt(self, client):
        client.token_endpoint = "https://example.com/token"

        csj = ClientSecretJWT(client)
        cis = AccessTokenRequest()

        http_args = csj.construct(cis, algorithm="HS256")
        assert cis["client_assertion_type"] == JWT_BEARER
        assert "client_assertion" in cis
        cas = cis["client_assertion"]
        _jwt = JWT().unpack(cas)
        jso = _jwt.payload()
        assert _eq(jso.keys(), ["aud", "iss", "sub", "jti", "exp", "iat"])
        assert _jwt.headers == {'alg': 'HS256'}

        _rj = JWS()
        info = _rj.verify_compact(cas, [SYMKey(key=client.client_secret)])

        assert _eq(info.keys(), ["aud", "iss", "sub", "jti", "exp", "iat"])
Exemple #24
0
    def test_client_secret_jwt(self, client):
        client.token_endpoint = "https://example.com/token"

        csj = ClientSecretJWT(client)
        cis = AccessTokenRequest()

        http_args = csj.construct(cis, algorithm="HS256")
        assert cis["client_assertion_type"] == JWT_BEARER
        assert "client_assertion" in cis
        cas = cis["client_assertion"]
        _jwt = JWT().unpack(cas)
        jso = _jwt.payload()
        assert _eq(jso.keys(), ["aud", "iss", "sub", "jti", "exp", "iat"])
        assert _jwt.headers == {'alg': 'HS256'}

        _rj = JWS()
        info = _rj.verify_compact(cas, [SYMKey(key=client.client_secret)])

        assert _eq(info.keys(), ["aud", "iss", "sub", "jti", "exp", "iat"])
Exemple #25
0
    def assert_registstration_req(self, request, sign_key_str):
        split_path = request.path_url.lstrip("/").split("/")
        assert len(split_path) == 2

        jwks = split_path[1]

        # Verify signature
        public_key = import_rsa_key(private_to_public_key(sign_key_str))
        sign_key = RSAKey().load_key(public_key)
        sign_key.use = "sig"
        _jw = jws.factory(jwks)
        _jw.verify_compact(jwks, [sign_key])

        # Verify JWT
        _jwt = JWT().unpack(jwks)
        consent_args = _jwt.payload()

        assert "attr" in consent_args
        assert "redirect_endpoint" in consent_args
        assert "id" in consent_args
    def test_construct_authz_req_with_request_object(self, tmpdir):
        path = tmpdir.strpath
        request_uri_args = {
            "local_dir": path,
            "base_path": "http://example.com/"
        }
        areq = self.client.construct_AuthorizationRequest(request_method="file",
                                                          **request_uri_args)
        p = urlparse(areq["request_uri"])
        local_path = os.path.join(path, p.path.lstrip("/"))
        with open(local_path) as f:
            data = f.read()
        jwt = JWT().unpack(data)
        payload = jwt.payload()

        assert payload["redirect_uri"] == "http://example.com/redirect"
        assert payload["client_id"] == CLIENT_ID
        assert "nonce" in payload

        os.remove(local_path)
Exemple #27
0
    def assert_registstration_req(self, request, sign_key_str):
        split_path = request.path_url.lstrip("/").split("/")
        assert len(split_path) == 2

        jwks = split_path[1]

        # Verify signature
        public_key = import_rsa_key(private_to_public_key(sign_key_str))
        sign_key = RSAKey().load_key(public_key)
        sign_key.use = "sig"
        _jw = jws.factory(jwks)
        _jw.verify_compact(jwks, [sign_key])

        # Verify JWT
        _jwt = JWT().unpack(jwks)
        consent_args = _jwt.payload()

        assert "attr" in consent_args
        assert "redirect_endpoint" in consent_args
        assert "id" in consent_args
Exemple #28
0
def set_crosswalk_with_id_token(backend, user, response, *args, **kwargs):
    if backend.name == 'verifymyidentity-openidconnect':

        if 'id_token' in response.keys():
            id_token = response.get('id_token')
            parsed_id_token = JWT().unpack(id_token)
            payload = parsed_id_token.payload()

            if 'document' in payload:
                for doc in payload['document']:
                    # Does it already exist?
                    cw, g_o_c = Crosswalk.objects.get_or_create(
                        user=user,
                        user_identifier=doc['num'],
                        user_id_type=doc['type'])
                    if "azurehealthcareapis.com" in doc['uri']:
                        cw.use_client_credentials = True
                    cw.fhir_source = doc['uri']
                    if doc['type'] == "PATIENT_ID_FHIR":
                        cw.fhir_patient_id = doc['num']
                    cw.save()
def verify_signed_id_token(token, key=None, jwks=None):
    jwt = JWT().unpack(token)
    payload = jwt.payload()
    issuer = payload['iss']
    provider_keys = None

    if jwt.headers['alg'].startswith('HS') and not key:
        raise IDTokenVerificationError(
            'No symmetric key provided for signature using \'{}\' algorithm.'.format(
                jwt.headers['alg']))

    if key:
        provider_keys = _create_symmetric_key(issuer, key)
    elif jwks:
        provider_keys = _parse_provider_keys_from_jwks(issuer, jwks)
    elif jwt.headers['alg'] != 'none':  # don't fetch keys for unsigned JWT
        provider_keys = _fetch_provider_keys(issuer)

    try:
        return IdToken().from_jwt(token, keyjar=provider_keys).to_json()
    except (BadSignature, NoSuitableSigningKeys) as e:
        raise IDTokenVerificationError(
            'No key that could be used to verify the signature could be found.')
Exemple #30
0
    def test_client_secret_jwt(self, client):
        client.token_endpoint = "https://example.com/token"
        client.provider_info = {'issuer': 'https://example.com/',
                                'token_endpoint': "https://example.com/token"}

        csj = ClientSecretJWT(client)
        cis = AccessTokenRequest()

        csj.construct(cis, algorithm="HS256",
                      authn_endpoint='userinfo')
        assert cis["client_assertion_type"] == JWT_BEARER
        assert "client_assertion" in cis
        cas = cis["client_assertion"]
        _jwt = JWT().unpack(cas)
        jso = _jwt.payload()
        assert _eq(jso.keys(), ["aud", "iss", "sub", "jti", "exp", "iat"])
        assert _jwt.headers == {'alg': 'HS256'}

        _rj = JWS()
        info = _rj.verify_compact(
            cas, [SYMKey(k=b64e(as_bytes(client.client_secret)))])

        assert _eq(info.keys(), ["aud", "iss", "sub", "jti", "exp", "iat"])
        assert info['aud'] == [client.provider_info['issuer']]
    def from_jwt(self, txt, key=None, verify=True, keyjar=None, **kwargs):
        """
        Given a signed and/or encrypted JWT, verify its correctness and then
        create a class instance from the content.

        :param txt: The JWT
        :param key: keys that might be used to decrypt and/or verify the
            signature of the JWT
        :param verify: Whether the signature should be verified or not
        :param keyjar: A KeyJar that might contain the necessary key.
        :param kwargs: Extra key word arguments
        :return: A class instance
        """
        # if key is None and keyjar is not None:
        #     key = keyjar.get_verify_key(owner="")
        # elif key is None:
        #     key = []
        #
        # if keyjar is not None and "sender" in kwargs:
        #     key.extend(keyjar.get_verify_key(owner=kwargs["sender"]))

        _jw = jwe.factory(txt)
        if _jw:
            logger.debug("JWE headers: {}".format(_jw.jwt.headers))

            if "algs" in kwargs and "encalg" in kwargs["algs"]:
                if kwargs["algs"]["encalg"] != _jw["alg"]:
                    raise WrongEncryptionAlgorithm("%s != %s" % (_jw["alg"], kwargs["algs"]["encalg"]))
                if kwargs["algs"]["encenc"] != _jw["enc"]:
                    raise WrongEncryptionAlgorithm("%s != %s" % (_jw["enc"], kwargs["algs"]["encenc"]))
            if keyjar:
                dkeys = keyjar.get_decrypt_key(owner="")
                if "sender" in kwargs:
                    dkeys.extend(keyjar.get_verify_key(owner=kwargs["sender"]))
            elif key:
                dkeys = key
            else:
                dkeys = []

            logger.debug('Decrypt class: {}'.format(_jw.__class__))
            _res = _jw.decrypt(txt, dkeys)
            logger.debug('decrypted message:{}'.format(_res))
            if isinstance(_res, tuple):
                txt = as_unicode(_res[0])
            elif isinstance(_res, list) and len(_res) == 2:
                txt = as_unicode(_res[0])
            else:
                txt = as_unicode(_res)
            self.jwe_header = _jw.jwt.headers

        _jw = jws.factory(txt)
        if _jw:
            if "algs" in kwargs and "sign" in kwargs["algs"]:
                _alg = _jw.jwt.headers["alg"]
                if kwargs["algs"]["sign"] != _alg:
                    raise WrongSigningAlgorithm("%s != %s" % (_alg, kwargs["algs"]["sign"]))
            try:
                _jwt = JWT().unpack(txt)
                jso = _jwt.payload()
                _header = _jwt.headers

                if key is None and keyjar is not None:
                    key = keyjar.get_verify_key(owner="")
                elif key is None:
                    key = []

                if keyjar is not None and "sender" in kwargs:
                    key.extend(keyjar.get_verify_key(owner=kwargs["sender"]))

                logger.debug("Raw JSON: {}".format(sanitize(jso)))
                logger.debug("JWS header: {}".format(sanitize(_header)))
                if _header["alg"] == "none":
                    pass
                elif verify:
                    if keyjar:
                        key = self.get_verify_keys(keyjar, key, jso, _header,
                                                   _jw, **kwargs)

                    if "alg" in _header and _header["alg"] != "none":
                        if not key:
                            raise MissingSigningKey(
                                "alg=%s" % _header["alg"])

                    logger.debug("Found signing key.")
                    try:
                        _jw.verify_compact(txt, key)
                    except NoSuitableSigningKeys:
                        if keyjar:
                            update_keyjar(keyjar)
                            key = self.get_verify_keys(keyjar, key, jso,
                                                       _header, _jw, **kwargs)
                            _jw.verify_compact(txt, key)
            except Exception:
                raise
            else:
                self.jws_header = _jwt.headers
        else:
            jso = json.loads(txt)

        self.jwt = txt
        return self.from_dict(jso)
Exemple #32
0
    def from_jwt(self, txt, key=None, verify=True, keyjar=None, **kwargs):
        """
        Given a signed and/or encrypted JWT, verify its correctness and then
        create a class instance from the content.

        :param txt: The JWT
        :param key: keys that might be used to decrypt and/or verify the
            signature of the JWT
        :param verify: Whether the signature should be verified or not
        :param keyjar: A KeyJar that might contain the necessary key.
        :param kwargs: Extra key word arguments
        :return: A class instance
        """
        if key is None and keyjar is not None:
            key = keyjar.get_verify_key(owner="")
        elif key is None:
            key = []

        if keyjar is not None and "sender" in kwargs:
            key.extend(keyjar.get_verify_key(owner=kwargs["sender"]))

        _jw = jwe.factory(txt)
        if _jw:
            if "algs" in kwargs and "encalg" in kwargs["algs"]:
                try:
                    assert kwargs["algs"]["encalg"] == _jw["alg"]
                except AssertionError:
                    raise WrongEncryptionAlgorithm("%s != %s" % (
                        _jw["alg"], kwargs["algs"]["encalg"]))
                try:
                    assert kwargs["algs"]["encenc"] == _jw["enc"]
                except AssertionError:
                    raise WrongEncryptionAlgorithm("%s != %s" % (
                        _jw["enc"], kwargs["algs"]["encenc"]))
            if keyjar:
                dkeys = keyjar.get_decrypt_key(owner="")
            elif key:
                dkeys = key
            else:
                dkeys = []

            txt = _jw.decrypt(txt, dkeys)
            self.jwe_header = _jw.jwt.headers

        _jw = jws.factory(txt)
        if _jw:
            if "algs" in kwargs and "sign" in kwargs["algs"]:
                _alg = _jw.jwt.headers["alg"]
                try:
                    assert kwargs["algs"]["sign"] == _alg
                except AssertionError:
                    raise WrongSigningAlgorithm("%s != %s" % (
                        _alg, kwargs["algs"]["sign"]))
            try:
                _jwt = JWT().unpack(txt)
                jso = _jwt.payload()
                _header = _jwt.headers

                logger.debug("Raw JSON: {}".format(jso))
                logger.debug("header: {}".format(_header))
                if _header["alg"] == "none":
                    pass
                else:
                    if keyjar:
                        logger.debug("Issuer keys: {}".format(keyjar.keys()))
                        try:
                            _iss = jso["iss"]
                        except KeyError:
                            pass
                        else:
                            if "jku" in _header:
                                if not keyjar.find(_header["jku"], _iss):
                                    # This is really questionable
                                    try:
                                        if kwargs["trusting"]:
                                            keyjar.add(jso["iss"], _header["jku"])
                                    except KeyError:
                                        pass

                            if "kid" in _header and _header["kid"]:
                                _jw["kid"] = _header["kid"]
                                try:
                                    _key = keyjar.get_key_by_kid(_header["kid"],
                                                                 _iss)
                                    if _key:
                                        key.append(_key)
                                except KeyError:
                                    pass

                        try:
                            self._add_key(keyjar, kwargs["opponent_id"], key)
                        except KeyError:
                            pass

                    if verify:
                        if keyjar:
                            for ent in ["iss", "aud", "client_id"]:
                                if ent not in jso:
                                    continue
                                if ent == "aud":
                                    # list or basestring
                                    if isinstance(jso["aud"], six.string_types):
                                        _aud = [jso["aud"]]
                                    else:
                                        _aud = jso["aud"]
                                    for _e in _aud:
                                        self._add_key(keyjar, _e, key)
                                else:
                                    self._add_key(keyjar, jso[ent], key)

                        if "alg" in _header and _header["alg"] != "none":
                            if not key:
                                raise MissingSigningKey(
                                    "alg=%s" % _header["alg"])

                        logger.debug("Verify keys: {}".format(key))
                        _jw.verify_compact(txt, key)
            except Exception:
                raise
            else:
                self.jws_header = _jwt.headers
        else:
            jso = json.loads(txt)

        return self.from_dict(jso)
    def from_jwt(self, txt, key=None, verify=True, keyjar=None, **kwargs):
        """
        Given a signed and/or encrypted JWT, verify its correctness and then
        create a class instance from the content.

        :param txt: The JWT
        :param key: keys that might be used to decrypt and/or verify the
            signature of the JWT
        :param verify: Whether the signature should be verified or not
        :param keyjar: A KeyJar that might contain the necessary key.
        :param kwargs: Extra key word arguments
        :return: A class instance
        """
        if key is None and keyjar is not None:
            key = keyjar.get_verify_key(owner="")
        elif key is None:
            key = []

        if keyjar is not None and "sender" in kwargs:
            key.extend(keyjar.get_verify_key(owner=kwargs["sender"]))

        _jw = jwe.factory(txt)
        if _jw:
            if "algs" in kwargs and "encalg" in kwargs["algs"]:
                try:
                    assert kwargs["algs"]["encalg"] == _jw["alg"]
                except AssertionError:
                    raise WrongEncryptionAlgorithm("%s != %s" % (
                        _jw["alg"], kwargs["algs"]["encalg"]))
                try:
                    assert kwargs["algs"]["encenc"] == _jw["enc"]
                except AssertionError:
                    raise WrongEncryptionAlgorithm("%s != %s" % (
                        _jw["enc"], kwargs["algs"]["encenc"]))
            if keyjar:
                dkeys = keyjar.get_decrypt_key(owner="")
            elif key:
                dkeys = key
            else:
                dkeys = []

            txt = as_unicode(_jw.decrypt(txt, dkeys))
            self.jwe_header = _jw.jwt.headers

        _jw = jws.factory(txt)
        if _jw:
            if "algs" in kwargs and "sign" in kwargs["algs"]:
                _alg = _jw.jwt.headers["alg"]
                try:
                    assert kwargs["algs"]["sign"] == _alg
                except AssertionError:
                    raise WrongSigningAlgorithm("%s != %s" % (
                        _alg, kwargs["algs"]["sign"]))
            try:
                _jwt = JWT().unpack(txt)
                jso = _jwt.payload()
                _header = _jwt.headers

                logger.debug("Raw JSON: {}".format(jso))
                logger.debug("header: {}".format(_header))
                if _header["alg"] == "none":
                    pass
                elif verify:
                    if keyjar:
                        key = self.get_verify_keys(keyjar, key, jso, _header,
                                                   _jw, **kwargs)

                    if "alg" in _header and _header["alg"] != "none":
                        if not key:
                            raise MissingSigningKey(
                                "alg=%s" % _header["alg"])

                    logger.debug("Verify keys: {}".format(key))
                    try:
                        _jw.verify_compact(txt, key)
                    except NoSuitableSigningKeys:
                        if keyjar:
                            update_keyjar(keyjar)
                            key = self.get_verify_keys(keyjar, key, jso,
                                                       _header, _jw, **kwargs)
                            _jw.verify_compact(txt, key)
            except Exception:
                raise
            else:
                self.jws_header = _jwt.headers
        else:
            jso = json.loads(txt)

        return self.from_dict(jso)
Exemple #34
0
    def from_jwt(self, txt, key=None, verify=True, keyjar=None, **kwargs):
        """
        Given a signed and/or encrypted JWT, verify its correctness and then
        create a class instance from the content.

        :param txt: The JWT
        :param key: keys that might be used to decrypt and/or verify the
            signature of the JWT
        :param verify: Whether the signature should be verified or not
        :param keyjar: A KeyJar that might contain the necessary key.
        :param kwargs: Extra key word arguments
        :return: A class instance
        """
        if key is None and keyjar is not None:
            key = keyjar.get_verify_key(owner="")
        elif key is None:
            key = []

        if keyjar is not None and "sender" in kwargs:
            key.extend(keyjar.get_verify_key(owner=kwargs["sender"]))

        _jw = jwe.factory(txt)
        if _jw:
            if "algs" in kwargs and "encalg" in kwargs["algs"]:
                try:
                    assert kwargs["algs"]["encalg"] == _jw["alg"]
                except AssertionError:
                    raise WrongEncryptionAlgorithm(
                        "%s != %s" % (_jw["alg"], kwargs["algs"]["encalg"]))
                try:
                    assert kwargs["algs"]["encenc"] == _jw["enc"]
                except AssertionError:
                    raise WrongEncryptionAlgorithm(
                        "%s != %s" % (_jw["enc"], kwargs["algs"]["encenc"]))
            if keyjar:
                dkeys = keyjar.get_decrypt_key(owner="")
            elif key:
                dkeys = key
            else:
                dkeys = []

            txt = _jw.decrypt(txt, dkeys)
            self.jwe_header = _jw.jwt.headers

        _jw = jws.factory(txt)
        if _jw:
            if "algs" in kwargs and "sign" in kwargs["algs"]:
                _alg = _jw.jwt.headers["alg"]
                try:
                    assert kwargs["algs"]["sign"] == _alg
                except AssertionError:
                    raise WrongSigningAlgorithm("%s != %s" %
                                                (_alg, kwargs["algs"]["sign"]))
            try:
                _jwt = JWT().unpack(txt)
                jso = _jwt.payload()
                _header = _jwt.headers

                logger.debug("Raw JSON: {}".format(jso))
                logger.debug("header: {}".format(_header))
                if _header["alg"] == "none":
                    pass
                else:
                    if keyjar:
                        logger.debug("Issuer keys: {}".format(keyjar.keys()))
                        try:
                            _iss = jso["iss"]
                        except KeyError:
                            pass
                        else:
                            if "jku" in _header:
                                if not keyjar.find(_header["jku"], _iss):
                                    # This is really questionable
                                    try:
                                        if kwargs["trusting"]:
                                            keyjar.add(jso["iss"],
                                                       _header["jku"])
                                    except KeyError:
                                        pass

                            if "kid" in _header and _header["kid"]:
                                _jw["kid"] = _header["kid"]
                                try:
                                    _key = keyjar.get_key_by_kid(
                                        _header["kid"], _iss)
                                    if _key:
                                        key.append(_key)
                                except KeyError:
                                    pass

                        try:
                            self._add_key(keyjar, kwargs["opponent_id"], key)
                        except KeyError:
                            pass

                    if verify:
                        if keyjar:
                            for ent in ["iss", "aud", "client_id"]:
                                if ent not in jso:
                                    continue
                                if ent == "aud":
                                    # list or basestring
                                    if isinstance(jso["aud"],
                                                  six.string_types):
                                        _aud = [jso["aud"]]
                                    else:
                                        _aud = jso["aud"]
                                    for _e in _aud:
                                        self._add_key(keyjar, _e, key)
                                else:
                                    self._add_key(keyjar, jso[ent], key)

                        if "alg" in _header and _header["alg"] != "none":
                            if not key:
                                raise MissingSigningKey("alg=%s" %
                                                        _header["alg"])

                        logger.debug("Verify keys: {}".format(key))
                        _jw.verify_compact(txt, key)
            except Exception:
                raise
            else:
                self.jws_header = _jwt.headers
        else:
            jso = json.loads(txt)

        return self.from_dict(jso)