Exemplo n.º 1
0
    def validate_access_token_request(self):
        """
        Override the parent method from authlib to not fail immediately for
        public clients.
        """
        client = self.authenticate_token_endpoint_client()
        if not client.check_grant_type(self.GRANT_TYPE):
            raise UnauthorizedClientError(uri=self.uri)
        self._authenticated_client = client

        refresh_token = self.params.get("refresh_token")
        if refresh_token is None:
            raise InvalidRequestError('Missing "refresh_token" in request.',
                                      uri=self.uri)

        refresh_claims = self.authenticate_refresh_token(refresh_token)
        if not refresh_claims:
            raise InvalidRequestError('Invalid "refresh_token" in request.',
                                      uri=self.uri)

        scope = self.params.get("scope")
        if scope:
            original_scope = refresh_claims["scope"]
            if not original_scope:
                raise InvalidScopeError(uri=self.uri)
            original_scope = set(scope_to_list(original_scope))
            if not original_scope.issuperset(set(scope_to_list(scope))):
                raise InvalidScopeError(uri=self.uri)

        self._authenticated_token = refresh_claims
Exemplo n.º 2
0
 def scope_insufficient(self, token, scope, operator='AND'):
     if not scope:
         return False
     token_scopes = set(scope_to_list(token['scope']))
     resource_scopes = set(scope_to_list(scope))
     if operator == 'AND':
         return not token_scopes.issuperset(resource_scopes)
     if operator == 'OR':
         return not token_scopes & resource_scopes
     if callable(operator):
         return not operator(token_scopes, resource_scopes)
     raise ValueError('Invalid operator value')
Exemplo n.º 3
0
    def generate_id_token(self,
                          token,
                          request,
                          nonce=None,
                          auth_time=None,
                          code=None):
        scopes = scope_to_list(token['scope'])
        if not scopes or scopes[0] != 'openid':
            return None

        # TODO: merge scopes and claims
        user_info = self.generate_user_info(request.user, scopes)

        config = self.server.config
        alg = config['jwt_alg']

        payload = self.generate_id_token_payload(
            alg,
            config['jwt_iss'],
            [request.client.client_id],
            config['jwt_exp'],
            nonce=nonce,
            auth_time=auth_time,
            code=code,
            access_token=token.get('access_token'),
        )
        payload.update(user_info)
        return _jwt_encode(alg, payload, config['jwt_key'])
Exemplo n.º 4
0
def generate_id_token(key,
                      token,
                      request,
                      alg,
                      iss,
                      exp,
                      nonce=None,
                      auth_time=None,
                      code=None):
    scopes = scope_to_list(token['scope'])
    # TODO: merge scopes and claims
    user_info = _generate_user_info(request.user, scopes)

    payload = _generate_id_token_payload(
        alg,
        iss,
        [request.client.client_id],
        exp=exp,
        nonce=nonce,
        auth_time=auth_time,
        code=code,
        access_token=token.get('access_token'),
    )
    payload.update(user_info)
    return _jwt_encode(alg, payload, key)
Exemplo n.º 5
0
    def _validate_token_scope(self, token):
        """
        OVERRIDES method from authlib.

        Why? Becuase our "token" is not a class with `get_scope` method.
        So we just need to treat it like a dictionary.
        """
        scope = self.request.scope
        if not scope:
            return

        # token is dict so just get the scope, don't use get_scope()
        original_scope = token.get("aud")
        if not original_scope:
            raise InvalidScopeError()

        original_scope = set(scope_to_list(original_scope))
        if not original_scope.issuperset(set(scope_to_list(scope))):
            raise InvalidScopeError()
Exemplo n.º 6
0
    def generate_id_token(self,
                          token,
                          request,
                          nonce=None,
                          auth_time=None,
                          code=None):
        scopes = scope_to_list(token['scope'])
        if not scopes or scopes[0] != 'openid':
            return None

        # TODO: merge scopes and claims
        user_info = self.generate_user_info(request.user, scopes)

        now = int(time.time())
        if auth_time is None:
            auth_time = now

        config = self.server.config
        payload = {
            'iss': config['jwt_iss'],
            'aud': [request.client.client_id],
            'iat': now,
            'exp': now + config['jwt_exp'],
            'auth_time': auth_time,
        }
        if nonce:
            payload['nonce'] = nonce

        # calculate at_hash
        alg = config['jwt_alg']

        access_token = token.get('access_token')
        if access_token:
            payload['at_hash'] = to_native(create_half_hash(access_token, alg))

        # calculate c_hash
        if code:
            payload['c_hash'] = to_native(create_half_hash(code, alg))

        payload.update(user_info)
        jwt = JWT(algorithms=alg)
        header = {'alg': alg}

        key = config['jwt_key']
        if isinstance(key, dict):
            # JWK set format
            if 'keys' in key:
                key = random.choice(key['keys'])
                header['kid'] = key['kid']
            elif 'kid' in key:
                header['kid'] = key['kid']

        return to_native(jwt.encode(header, payload, key))
Exemplo n.º 7
0
    def generate_id_token(self,
                          token,
                          request,
                          nonce=None,
                          auth_time=None,
                          code=None):

        scopes = scope_to_list(token['scope'])
        if not scopes or scopes[0] != 'openid':
            return None

        # TODO: merge scopes and claims
        user_info = self.generate_user_info(request.user, scopes)

        now = int(time.time())
        if auth_time is None:
            auth_time = now

        config = self.server.config
        payload = {
            'iss': config['jwt_iss'],
            'aud': [request.client.client_id],
            'iat': now,
            'exp': now + token['expires_in'],
            'auth_time': auth_time,
        }
        if nonce:
            payload['nonce'] = nonce

        # calculate at_hash
        alg = config.get('jwt_alg', 'HS256')

        access_token = token.get('access_token')
        if access_token:
            at_hash = to_unicode(create_half_hash(access_token, alg))
            payload['at_hash'] = at_hash

        # calculate c_hash
        if code:
            payload['c_hash'] = to_unicode(create_half_hash(code, alg))

        payload.update(user_info)
        jwt = JWT(algorithms=alg)
        header = {'alg': alg}
        key = config['jwt_key']
        id_token = jwt.encode(header, payload, key)
        return to_unicode(id_token)
Exemplo n.º 8
0
    def create_authorization_code(self, client, grant_user, request):

        # instead of creating a shared-secret auth code bound to the client in the DB,
        # we already create the id token info but send it to the client encrypted.

        token_info = {
            'sub':
            grant_user.generate_user_info(scope_to_list(request.scope))['sub'],
            'scope':
            request.scope,
            'auth_time':
            int(time.time()),
            'redirect_uri':
            client.redirect_uri,
            'client_id':
            client.client_id,
            'nonce':
            request.data.get('nonce'),
        }

        return encryption.encrypt_and_serialize(json.dumps(token_info))
Exemplo n.º 9
0
def is_openid_request(request):
    scopes = scope_to_list(request.scope)
    # openid should be the first scope
    return scopes and scopes[0] == 'openid'
Exemplo n.º 10
0
def is_openid_scope(scope):
    scopes = scope_to_list(scope)
    return scopes and scopes[0] == 'openid'