Ejemplo n.º 1
0
def get_current_jwt_token(request):
    """Get current JWT token for authenticated principal"""
    manager = query_utility(ISecurityManager)
    if manager is None:
        raise HTTPServiceUnavailable()
    configuration = IJWTSecurityConfiguration(manager)
    if not configuration.enabled:
        raise HTTPServiceUnavailable()
    if Authenticated not in request.effective_principals:
        raise HTTPForbidden()
    custom_claims = request.params.get('claims', {})
    request.response.cache_expires(configuration.refresh_expiration)
    return {
        'status':
        'success',
        configuration.access_token_name:
        create_jwt_token(request,
                         request.authenticated_userid,
                         expiration=configuration.access_expiration,
                         obj=ACCESS_OBJECT,
                         **custom_claims),
        configuration.refresh_token_name:
        create_jwt_token(request,
                         request.authenticated_userid,
                         expiration=configuration.refresh_expiration,
                         obj=REFRESH_OBJECT)
    }
Ejemplo n.º 2
0
 def get_tokens(self, request, credentials):  # pylint: disable=unused-argument
     """Get new tokens from authentication authority"""
     configuration = IJWTSecurityConfiguration(self.context)
     method, service = configuration.get_token_service  # pylint: disable=unpacking-non-sequence
     rest_service = '{}{}'.format(configuration.authority, service)
     if method == 'GET':
         rest_request = requests.request(method,
                                         rest_service,
                                         params=credentials.attributes,
                                         allow_redirects=False,
                                         verify=configuration.verify_ssl)
     else:
         rest_request = requests.request(method,
                                         rest_service,
                                         data=credentials.attributes,
                                         allow_redirects=False,
                                         verify=configuration.verify_ssl)
     status_code = rest_request.status_code
     if status_code == requests.codes.ok:  # pylint: disable=no-member
         result = rest_request.json()
         result[configuration.access_token_name] = \
             result.pop(configuration.proxy_access_token_name)
         result[configuration.refresh_token_name] = \
             result.pop(configuration.proxy_refresh_token_name)
         return status_code, result
     return status_code, {}
Ejemplo n.º 3
0
def refresh_jwt_token(request):
    """JWT token refresh service"""
    sm = query_utility(ISecurityManager)  # pylint: disable=invalid-name
    if sm is None:
        raise HTTPServiceUnavailable()
    configuration = IJWTSecurityConfiguration(sm)
    if not configuration.enabled:
        raise HTTPServiceUnavailable()
    # user remote authentication authority
    if configuration.proxy_mode:
        handler = IJWTProxyHandler(sm, None)
        if handler is not None:
            status_code, token = handler.refresh_token(request)  # pylint: disable=assignment-from-no-return
            request.response.status_code = status_code
            return token
    # refresh token locally
    claims = get_jwt_claims(request)
    if not claims:
        raise HTTPForbidden()
    principal_id = claims.get('sub')
    if not principal_id:
        raise HTTPUnauthorized()
    params = request.params if TEST_MODE else request.validated
    custom_claims = params.get('claims', {})
    return {
        'status':
        'success',
        configuration.access_token_name:
        create_jwt_token(request,
                         principal_id,
                         expiration=configuration.access_expiration,
                         obj=ACCESS_OBJECT,
                         **custom_claims)
    }
Ejemplo n.º 4
0
 def configuration(self):  # pylint: disable=no-self-use
     """JWT configuration getter"""
     try:
         manager = query_utility(ISecurityManager)
         if manager is not None:
             return IJWTSecurityConfiguration(manager)
     except ConnectionStateError:
         return None
     return None
Ejemplo n.º 5
0
def verify_jwt_token(request):
    """JWT token verification view"""
    manager = query_utility(ISecurityManager)
    if manager is None:
        raise HTTPServiceUnavailable()
    configuration = IJWTSecurityConfiguration(manager)
    if not configuration.enabled:
        raise HTTPServiceUnavailable()
    claims = get_jwt_claims(request)
    if not claims:
        raise HTTPForbidden()
    request.response.status_code = HTTPAccepted.code
    return {'status': 'success'}
Ejemplo n.º 6
0
    def get_claims(self, request, obj=None):
        """Get claims from provided request authorization"""
        authorization = getattr(request, 'authorization', None)
        if authorization is None:
            authorization = request.headers.get('Authorization')
        else:
            authorization = ' '.join(authorization)
        if not authorization:
            return HTTPUnauthorized.code, {}
        configuration = IJWTSecurityConfiguration(self.context)

        # Check Beaker cache
        tokens_cache = None
        cache_key = None
        if configuration.use_cache:
            cache_key = authorization
            if obj:
                cache_key = '{}::{}'.format(cache_key, obj)
            tokens_cache = get_cache(JWT_PROXY_CACHE_NAME,
                                     configuration.selected_cache,
                                     JWT_PROXY_TOKENS_NAMESPACE)
            try:
                claims = tokens_cache.get_value(cache_key)
            except KeyError:
                pass
            else:
                return HTTPOk.code, claims

        # Call authority REST API
        method, service = configuration.get_claims_service  # pylint: disable=unpacking-non-sequence
        rest_service = '{}{}'.format(configuration.authority, service)
        params = {}
        data = {}
        if obj:
            if method == 'GET':
                params['obj'] = obj
            else:
                data['obj'] = obj
        rest_request = requests.request(
            method,
            rest_service,
            params=params,
            data=data,
            headers={'Authorization': authorization})
        status_code = rest_request.status_code
        if status_code == requests.codes.ok:  # pylint: disable=no-member
            claims = rest_request.json()
            if tokens_cache is not None:
                tokens_cache.set_value(cache_key, claims)
            return status_code, claims
        return status_code, {}
Ejemplo n.º 7
0
 def refresh_token(self, request):
     """Get new access token with refresh token authorization"""
     configuration = IJWTSecurityConfiguration(self.context)
     method, service = configuration.refresh_token_service  # pylint: disable=unpacking-non-sequence
     rest_service = '{}{}'.format(configuration.authority, service)
     rest_request = requests.request(
         method,
         rest_service,
         headers={'Authorization': request.headers.get('Authorization')})
     status_code = rest_request.status_code
     if status_code == requests.codes.ok:  # pylint: disable=no-member
         result = rest_request.json()
         result[configuration.access_token_name] = \
             result.pop(configuration.proxy_access_token_name)
         return status_code, result
     return status_code, {}
Ejemplo n.º 8
0
def get_jwt_token(request):
    """REST login endpoint for JWT authentication"""
    # check security manager utility
    sm = query_utility(ISecurityManager)  # pylint: disable=invalid-name
    if sm is None:
        raise HTTPServiceUnavailable()
    configuration = IJWTSecurityConfiguration(sm)
    if not configuration.enabled:
        raise HTTPServiceUnavailable()
    # check request params
    params = request.params if TEST_MODE else request.validated
    login = params.get('login')
    if not login:
        raise HTTPBadRequest()
    credentials = Credentials('jwt', id=login, **params)
    # use remote authentication authority
    if configuration.proxy_mode:
        handler = IJWTProxyHandler(sm, None)
        if handler is not None:
            status_code, tokens = handler.get_tokens(request, credentials)  # pylint: disable=assignment-from-no-return
            request.response.status_code = status_code
            return tokens
    # authenticate principal in security manager
    principal_id = sm.authenticate(credentials, request)
    if principal_id is not None:
        custom_claims = params.get('claims', {})
        request.response.cache_expires(configuration.refresh_expiration)
        return {
            'status':
            'success',
            configuration.access_token_name:
            create_jwt_token(request,
                             principal_id,
                             expiration=configuration.access_expiration,
                             obj=ACCESS_OBJECT,
                             **custom_claims),
            configuration.refresh_token_name:
            create_jwt_token(request,
                             principal_id,
                             expiration=configuration.refresh_expiration,
                             obj=REFRESH_OBJECT)
        }
    request.response.status_code = HTTPUnauthorized.code
    return {
        'status': 'error',
        'message': request.localizer.translate(_("Invalid credentials!"))
    }
Ejemplo n.º 9
0
def get_jwt_claims(request):
    """Extract claims from provided JWT token"""
    sm = query_utility(ISecurityManager)  # pylint: disable=invalid-name
    if sm is None:
        raise HTTPServiceUnavailable()
    configuration = IJWTSecurityConfiguration(sm)
    if not configuration.enabled:
        raise HTTPServiceUnavailable()
    params = request.params if TEST_MODE else request.validated
    obj = params.get('obj')
    if configuration.proxy_mode:
        handler = IJWTProxyHandler(sm, None)
        if handler is not None:
            status_code, claims = handler.get_claims(request, obj)  # pylint: disable=assignment-from-no-return
            request.response.status_code = status_code
            return claims
    return get_request_claims(request, obj)
Ejemplo n.º 10
0
 def get_content(self):
     return IJWTSecurityConfiguration(self.context)