This blog delves into the step-by-step process of obtaining a token in Keystone, starting from the entry point 'authenticate_for_token' in the auth/controllers module, followed by validation, AuthInfo creation, AuthContext setup, and finally issuing the token through the token_provider_api."
104738368,9065522,关系数据模型详解,"['数据库', '数据模型', '数据库理论']
defauthenticate_for_token(self, request, auth=None)://auth是body体内容
"""Authenticate user and issue a token."""
include_catalog = 'nocatalog'notin request.params//如果不明确指定,则包含catalog
//request.params是url后缀的内容
*validate_issue_token_auth(auth)*//验证body体参数的合法性、有效性。
try:
auth_info = core.AuthInfo.create(auth=auth)
auth_context = core.AuthContext(extras={},
method_names=[],
bind={})
self.authenticate(request, auth_info, auth_context)
if auth_context.get('access_token_id'):
auth_info.set_scope(None, auth_context['project_id'], None)
self._check_and_set_default_scoping(auth_info, auth_context)
(domain_id, project_id, trust, unscoped) = auth_info.get_scope()
# NOTE(notmorgan): only methods that actually run and succeed will# be in the auth_context['method_names'] list. Do not blindly take# the values from auth_info, look at the authoritative values. Make# sure the set is unique.
method_names_set = set(auth_context.get('method_names', []))
method_names = list(method_names_set)
# Do MFA Rule Validation for the userifnot self._mfa_rules_validator.check_auth_methods_against_rules(
auth_context['user_id'], method_names_set):
raise exception.InsufficientAuthMethods(
user_id=auth_context['user_id'],
methods='[%s]' % ','.join(auth_info.get_method_names()))
expires_at = auth_context.get('expires_at')
token_audit_id = auth_context.get('audit_id')
is_domain = auth_context.get('is_domain')
(token_id, token_data) = self.token_provider_api.issue_token(
auth_context['user_id'], method_names, expires_at, project_id,
is_domain, domain_id, auth_context, trust, include_catalog,
parent_audit_id=token_audit_id)//获取token
# NOTE(wanghong): We consume a trust use only when we are using# trusts and have successfully issued a token.if trust:
self.trust_api.consume_use(trust['id'])
return render_token_data_response(token_id, token_data,
created=True)
except exception.TrustNotFound as e:
LOG.warning(six.text_type(e))
raise exception.Unauthorized(e)
2. validate_issue_token_auth
2.1 验证body体参数的合法性、有效性。
defvalidate_issue_token_auth(auth=None):if auth isNone:
return
validation.lazy_validate(schema.token_issue, auth)//基本的schema语法校验
user = auth['identity'].get('password', {}).get('user')//获取body体中user信息。
if user isnotNone:
if'id'notin user and'name'notin user://user中'id'、'name'至少包含一个
msg = _('Invalid input for field identity/password/user: ''id or name must be present.')
raise exception.SchemaValidationError(detail=msg)
domain = user.get('domain')
if domain isnotNone:
if'id'notin domain and'name'notin domain:
msg = _(
'Invalid input for field identity/password/user/domain: ''id or name must be present.')
raise exception.SchemaValidationError(detail=msg)
scope = auth.get('scope')
if scope isnotNoneand isinstance(scope, dict):
project = scope.get('project')
if project isnotNone:
if'id'notin project and'name'notin project:
msg = _(
'Invalid input for field scope/project: ''id or name must be present.')
raise exception.SchemaValidationError(detail=msg)
domain = project.get('domain')
if domain isnotNone:
if'id'notin domain and'name'notin domain:
msg = _(
'Invalid input for field scope/project/domain: ''id or name must be present.')
raise exception.SchemaValidationError(detail=msg)
domain = scope.get('domain')
if domain is