Use the instance service key for registry JWT signing
This commit is contained in:
parent
a4aa5cc02a
commit
8887f09ba8
26 changed files with 457 additions and 278 deletions
|
@ -1,12 +1,7 @@
|
|||
import logging
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from cryptography.hazmat.primitives.asymmetric.ec import EllipticCurvePublicNumbers
|
||||
from cryptography.hazmat.primitives.asymmetric.rsa import RSAPublicNumbers
|
||||
from flask import Blueprint, jsonify, abort, request, make_response
|
||||
from jwkest.jwk import keyrep, RSAKey, ECKey
|
||||
from jwt import get_unverified_header
|
||||
|
||||
import data.model
|
||||
|
@ -14,8 +9,7 @@ import data.model.service_keys
|
|||
from data.model.log import log_action
|
||||
|
||||
from app import app
|
||||
from auth.registry_jwt_auth import TOKEN_REGEX
|
||||
from util.security import strictjwt
|
||||
from util.security import jwtutil
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
@ -39,23 +33,13 @@ def _validate_jwk(jwk):
|
|||
abort(400)
|
||||
|
||||
|
||||
def _jwk_dict_to_public_key(jwk):
|
||||
jwkest_key = keyrep(jwk)
|
||||
if isinstance(jwkest_key, RSAKey):
|
||||
pycrypto_key = jwkest_key.key
|
||||
return RSAPublicNumbers(e=pycrypto_key.e, n=pycrypto_key.n).public_key(default_backend())
|
||||
elif isinstance(jwkest_key, ECKey):
|
||||
x, y = jwkest_key.get_key()
|
||||
return EllipticCurvePublicNumbers(x, y, jwkest_key.curve).public_key(default_backend())
|
||||
|
||||
|
||||
def _validate_jwt(encoded_jwt, jwk, service):
|
||||
public_key = _jwk_dict_to_public_key(jwk)
|
||||
public_key = jwtutil.jwk_dict_to_public_key(jwk)
|
||||
|
||||
try:
|
||||
strictjwt.decode(encoded_jwt, public_key, algorithms=['RS256'],
|
||||
jwtutil.decode(encoded_jwt, public_key, algorithms=['RS256'],
|
||||
audience=JWT_AUDIENCE, issuer=service)
|
||||
except strictjwt.InvalidTokenError:
|
||||
except jwtutil.InvalidTokenError:
|
||||
logger.exception('JWT validation failure')
|
||||
abort(400)
|
||||
|
||||
|
@ -122,7 +106,7 @@ def put_service_key(service, kid):
|
|||
abort(400)
|
||||
|
||||
jwt_header = request.headers.get(JWT_HEADER_NAME, '')
|
||||
match = TOKEN_REGEX.match(jwt_header)
|
||||
match = jwtutil.TOKEN_REGEX.match(jwt_header)
|
||||
if match is None:
|
||||
logger.error('Could not find matching bearer token')
|
||||
abort(400)
|
||||
|
@ -180,7 +164,7 @@ def put_service_key(service, kid):
|
|||
@key_server.route('/services/<service>/keys/<kid>', methods=['DELETE'])
|
||||
def delete_service_key(service, kid):
|
||||
jwt_header = request.headers.get(JWT_HEADER_NAME, '')
|
||||
match = TOKEN_REGEX.match(jwt_header)
|
||||
match = jwtutil.TOKEN_REGEX.match(jwt_header)
|
||||
if match is None:
|
||||
abort(400)
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ from auth.auth import require_session_login
|
|||
from data import model
|
||||
from endpoints.common import common_login, route_show_if
|
||||
from endpoints.web import render_page_template_with_routedata
|
||||
from util.security.strictjwt import decode, InvalidTokenError
|
||||
from util.security.jwtutil import decode, InvalidTokenError
|
||||
from util.validation import generate_valid_usernames
|
||||
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ import re
|
|||
|
||||
from flask import request, jsonify, abort
|
||||
|
||||
from app import app, userevents
|
||||
from app import app, userevents, instance_keys
|
||||
from data import model
|
||||
from auth.auth import process_auth
|
||||
from auth.auth_context import get_authenticated_user, get_validated_token, get_validated_oauth_token
|
||||
|
@ -14,7 +14,7 @@ from endpoints.v2 import v2_bp
|
|||
from endpoints.decorators import anon_protect
|
||||
from util.cache import no_cache
|
||||
from util.names import parse_namespace_repository, REPOSITORY_NAME_REGEX
|
||||
from util.security.registry_jwt import generate_jwt_object, build_context_and_subject
|
||||
from util.security.registry_jwt import generate_bearer_token, build_context_and_subject
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
@ -152,8 +152,6 @@ def generate_registry_jwt():
|
|||
|
||||
# Build the signed JWT.
|
||||
context, subject = build_context_and_subject(user, token, oauthtoken)
|
||||
|
||||
jwt_obj = generate_jwt_object(audience_param, subject, context, access, TOKEN_VALIDITY_LIFETIME_S,
|
||||
app.config)
|
||||
|
||||
return jsonify({'token': jwt_obj})
|
||||
token = generate_bearer_token(audience_param, subject, context, access,
|
||||
TOKEN_VALIDITY_LIFETIME_S, instance_keys)
|
||||
return jsonify({'token': token})
|
||||
|
|
|
@ -53,7 +53,6 @@ logging.captureWarnings(True)
|
|||
web = Blueprint('web', __name__)
|
||||
|
||||
STATUS_TAGS = app.config['STATUS_TAGS']
|
||||
JWT_ISSUER = app.config.get('JWT_AUTH_TOKEN_ISSUER')
|
||||
|
||||
|
||||
@web.route('/', methods=['GET'], defaults={'path': ''})
|
||||
|
|
Reference in a new issue