Handle empty scopes and always send the WWW-Authenticate header, as per spec
Fixes #1045
This commit is contained in:
parent
c8f43ed08e
commit
ca7d36bf14
10 changed files with 47 additions and 41 deletions
|
@ -3,13 +3,13 @@ import re
|
|||
|
||||
from jsonschema import validate, ValidationError
|
||||
from functools import wraps
|
||||
from flask import request
|
||||
from flask import request, url_for
|
||||
from flask.ext.principal import identity_changed, Identity
|
||||
from cryptography.x509 import load_pem_x509_certificate
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from cachetools import lru_cache
|
||||
|
||||
from app import app
|
||||
from app import app, get_app_url
|
||||
from .auth_context import set_grant_context, get_grant_context
|
||||
from .permissions import repository_read_grant, repository_write_grant
|
||||
from util.names import parse_namespace_repository
|
||||
|
@ -152,6 +152,18 @@ def build_context_and_subject(user, token, oauthtoken):
|
|||
return (context, ANONYMOUS_SUB)
|
||||
|
||||
|
||||
def get_auth_headers():
|
||||
""" Returns a dictionary of headers for auth responses. """
|
||||
headers = {}
|
||||
realm_auth_path = url_for('v2.generate_registry_jwt')
|
||||
authenticate = 'Bearer realm="{0}{1}",service="{2}"'.format(get_app_url(),
|
||||
realm_auth_path,
|
||||
app.config['SERVER_HOSTNAME'])
|
||||
headers['WWW-Authenticate'] = authenticate
|
||||
headers['Docker-Distribution-API-Version'] = 'registry/2.0'
|
||||
return headers
|
||||
|
||||
|
||||
def identity_from_bearer_token(bearer_token, max_signed_s, public_key):
|
||||
""" Process a bearer token and return the loaded identity, or raise InvalidJWTException if an
|
||||
identity could not be loaded. Expects tokens and grants in the format of the Docker registry
|
||||
|
@ -219,7 +231,7 @@ def load_public_key(certificate_file_path):
|
|||
return cert_obj.public_key()
|
||||
|
||||
|
||||
def process_jwt_auth(func):
|
||||
def process_registry_jwt_auth(func):
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs):
|
||||
logger.debug('Called with params: %s, %s', args, kwargs)
|
||||
|
@ -237,8 +249,7 @@ def process_jwt_auth(func):
|
|||
set_grant_context(context)
|
||||
logger.debug('Identity changed to %s', extracted_identity.id)
|
||||
except InvalidJWTException as ije:
|
||||
abort(401, message=ije.message)
|
||||
|
||||
abort(401, message=ije.message, headers=get_auth_headers())
|
||||
else:
|
||||
logger.debug('No auth header.')
|
||||
|
Reference in a new issue