def authenticate(self, context, auth_info): if 'token' in auth_info: try: response_data = {} userdata = json.loads(self._parse_cryptoken( auth_info['token'])) if not 'username' in userdata or not 'domain' in userdata: raise Unauthorized("Cannot retrieve user data") LOG.info("Accepted secret for user %s" % userdata['username']) uDict = self.identity_api.get_user_by_name( userdata['username'], userdata['domain']) if not uDict['enabled']: raise Unauthorized("User %s is disabled" % uDict['name']) response_data['user_id'] = uDict['id'] return base.AuthHandlerResponse(status=True, response_body=None, response_data=response_data) except UserNotFound: raise NotFound("Missing user") except Unauthorized as noAuthEx: LOG.error(str(noAuthEx)) raise except Exception: LOG.error("Cannot decrypt token", exc_info=True) raise Unauthorized('Cannot authenticate using sKey')
def authenticate(self, auth_payload): """Use HTTP_X_USER_NAME to look up the user in the identity backend. """ response_data = {} try: # trusted-key header configured? if CONF.cc_external.trusted_key_value: # check it secret = flask.request.environ[ CONF.cc_external.trusted_key_header] if secret != CONF.cc_external.trusted_key_value: raise KeyError except KeyError: LOG.error( "Authentication failed. Invalid trusted secret from: %s" % flask.request.environ.get('REMOTE_ADDR')) msg = _('Authentication requested from a untrusted source') raise exception.Unauthorized(msg) try: remote_user = flask.request.environ[ CONF.cc_external.user_name_header] user_ref = self._authenticate(remote_user) except Exception: msg = _('Unable to lookup user %s') % flask.request.environ.get( CONF.cc_external.user_name_header) raise exception.Unauthorized(msg) response_data['user_id'] = user_ref['id'] return base.AuthHandlerResponse(status=True, response_body=None, response_data=response_data)
def authenticate(self, request, auth_payload): """Authenticate mapped user and set an authentication context. :param request: keystone's request context :param auth_payload: the content of the authentication for a given method In addition to ``user_id`` in ``response_data``, this plugin sets ``group_ids``, ``OS-FEDERATION:identity_provider`` and ``OS-FEDERATION:protocol`` """ if 'id' in auth_payload: token_ref = self._get_token_ref(auth_payload) response_data = handle_scoped_token(request, token_ref, self.federation_api, self.identity_api) else: response_data = handle_unscoped_token( request, auth_payload, self.resource_api, self.federation_api, self.identity_api, self.assignment_api, self.role_api) return base.AuthHandlerResponse(status=True, response_body=None, response_data=response_data)
def authenticate(self, auth_payload, user_context=None): """Try to authenticate against the identity backend.""" user_info = password.auth_plugins.UserAuthInfo.create( auth_payload, 'password') # FIXME(gyee): identity.authenticate() can use some refactoring since # all we care is password matches try: res = PROVIDERS.identity_api.authenticate( user_id=user_info.user_id, password=user_info.password) except AssertionError: # authentication failed because of invalid username or password msg = 'Invalid username or password' raise exception.Unauthorized(msg) if not user_context: user_context = {} if 'user_id' not in user_context: user_context['user_id'] = user_info.user_id if 'extras' in res: user_context['extras'] = res['extras'] LOG.debug("authenticate %s" % user_context) if ('O' in RELEASES): # true when current version is Newton or upper from keystone.auth.plugins import base return base.AuthHandlerResponse(status=True, response_body=None, response_data=user_context)
def authenticate( self, request, auth_payload, ): """Use REMOTE_USER to look up the user in the identity backend. The user_id from the actual user from the REMOTE_USER env variable is placed in the response_data. """ response_data = {} if not request.remote_user: msg = _('No authenticated user') raise exception.Unauthorized(msg) try: user_ref = self._authenticate(request) except Exception: msg = _('Unable to lookup user %s') % request.remote_user raise exception.Unauthorized(msg) response_data['user_id'] = user_ref['id'] auth_type = (request.auth_type or '').lower() if 'kerberos' in CONF.token.bind and auth_type == 'negotiate': response_data.setdefault('bind', {})['kerberos'] = user_ref['name'] return base.AuthHandlerResponse(status=True, response_body=None, response_data=response_data)
def authenticate(self, request, auth_payload): """Try to authenticate using TOTP.""" response_data = {} user_info = plugins.TOTPUserInfo.create(auth_payload, METHOD_NAME) auth_passcode = auth_payload.get('user').get('passcode') credentials = self.credential_api.list_credentials_for_user( user_info.user_id, type='totp') valid_passcode = False for credential in credentials: try: generated_passcode = _generate_totp_passcode( credential['blob']) if auth_passcode == generated_passcode: valid_passcode = True break except (ValueError, KeyError): LOG.debug('No TOTP match; credential id: %s, user_id: %s', credential['id'], user_info.user_id) except (TypeError): LOG.debug('Base32 decode failed for TOTP credential %s', credential['id']) if not valid_passcode: # authentication failed because of invalid username or passcode msg = _('Invalid username or TOTP passcode') raise exception.Unauthorized(msg) response_data['user_id'] = user_info.user_id return base.AuthHandlerResponse(status=True, response_body=None, response_data=response_data)
def authenticate(self, context, auth_payload): response_data = {} if 'response' in auth_payload: if auth_payload['response'] != EXPECTED_RESPONSE: raise exception.Unauthorized('Wrong answer') response_data['user_id'] = DEMO_USER_ID return base.AuthHandlerResponse(status=True, response_body=None, response_data=response_data) else: return base.AuthHandlerResponse( status=False, response_body={ "challenge": "What's the name of your high school?" }, response_data=None)
def authenticate(self, request, auth_payload): """Try to authenticate against the identity backend.""" response_data = {} user_info = auth_plugins.UserAuthInfo.create(auth_payload, self.method) # Before we do anything else, make sure that this user is allowed # access from their source IP password_safelist.check_safelist(user_info.user_id, request.environ['REMOTE_ADDR']) try: PROVIDERS.identity_api.authenticate(request, user_id=user_info.user_id, password=user_info.password) except AssertionError: # authentication failed because of invalid username or password msg = _('Invalid username or password') raise exception.Unauthorized(msg) # Password auth succeeded, check two-factor # LOG.debug("OATH: Doing 2FA for user_info " + # ( "%s(%r)" % (user_info.__class__, user_info.__dict__) ) ) # LOG.debug("OATH: Doing 2FA for auth_payload " + # ( "%s(%r)" % (auth_payload.__class__, auth_payload) ) ) if 'totp' not in auth_payload['user']: LOG.debug("OATH: 2FA failed, missing totp param") msg = _('Missing two-factor token') raise exception.Unauthorized(msg) wtclient = wikitechclient.WikitechClient( CONF.oath.wikitech_host, CONF.oath.wikitech_consumer_token, CONF.oath.wikitech_consumer_secret, CONF.oath.wikitech_access_token, CONF.oath.wikitech_access_secret) valid = wtclient.oathvalidate(user_info.user_ref['name'], auth_payload['user']['totp']) if valid['enabled']: if valid['valid']: LOG.debug("OATH: 2FA passed") else: LOG.debug("OATH: 2FA failed") msg = _('Invalid two-factor token') raise exception.Unauthorized(msg) else: LOG.debug("OATH: user '%s' does not have 2FA enabled.", user_info.user_ref['name']) msg = _('2FA is not enabled; login forbidden') raise exception.Unauthorized(msg) response_data['user_id'] = user_info.user_id return base.AuthHandlerResponse(status=True, response_body=None, response_data=response_data)
def authenticate(self, request, auth_payload): """Try to authenticate against the identity backend and with TOTP.""" response_data = {} user_info = plugins.UserAuthInfo.create(auth_payload, METHOD_NAME) # First we check if the given user_id has totp credentials credentials = PROVIDERS.credential_api.list_credentials_for_user( user_info.user_id, type='totp') if credentials: # If the user has credentials, strip passcode from password user_password = user_info.password[:-utils.PASSCODE_LENGTH] auth_passcode = user_info.password[-utils.PASSCODE_LENGTH:] valid_passcode = False else: # If the user has no TOTP credentials, skip TOTP. user_password = user_info.password valid_passcode = True try: PROVIDERS.identity_api.authenticate( request, user_id=user_info.user_id, password=user_password) except AssertionError: # authentication failed because of invalid username or password msg = _('Invalid username or password') raise exception.Unauthorized(msg) for credential in credentials: try: generated_passcodes = utils._generate_totp_passcodes( credential['blob']) if auth_passcode in generated_passcodes: valid_passcode = True break except (ValueError, KeyError): LOG.debug('No TOTP match; credential id: %s, user_id: %s', credential['id'], user_info.user_id) except (TypeError): LOG.debug('Base32 decode failed for TOTP credential %s', credential['id']) if not valid_passcode: # authentication failed because of invalid passcode msg = _('Invalid TOTP passcode') raise exception.Unauthorized(msg) response_data['user_id'] = user_info.user_id return base.AuthHandlerResponse(status=True, response_body=None, response_data=response_data)
def authenticate(self, request, auth_payload): if 'id' not in auth_payload: raise exception.ValidationError(attribute='id', target='token') token_ref = self._get_token_ref(auth_payload) if token_ref.is_federated_user and self.federation_api: response_data = mapped.handle_scoped_token(request, token_ref, self.federation_api, self.identity_api) else: response_data = token_authenticate(request, token_ref) return base.AuthHandlerResponse(status=True, response_body=None, response_data=response_data)
def authenticate(self, auth_payload): """Try to authenticate using SecurID ober Radius""" response_data = {} user_info = plugins.TOTPUserInfo.create(auth_payload, METHOD_NAME) auth_passcode = auth_payload.get('user').get('passcode') LOG.info("Authenticating %s's SecurID passcode" % user_info.user_ref['name']) if not re.match(UID_REGEX, user_info.user_ref['name']): # authentication failed because of invalid username raise exception.Unauthorized( 'SecurID/Radius authentication is only supported for CID users' ) if not CONF.cc_radius.host or not CONF.cc_radius.port or not CONF.cc_radius.secret: raise exception.Unauthorized( 'SecurID/Radius backend service configuration is missing') try: if not radius.authenticate(CONF.cc_radius.secret, user_info.user_ref['name'], auth_passcode, host=CONF.cc_radius.host, port=CONF.cc_radius.port): LOG.info( "Authentication failed: SecurID token of '%s' invalid" % user_info.user_ref['name']) # authentication failed because of invalid username or passcode msg = _('Invalid username or passcode') raise exception.Unauthorized(msg) except exception.Unauthorized: raise except Exception as e: LOG.error( "Authentication failed: SecurID verification of '%s' failed: %s" % (user_info.user_ref['name'], e)) # authentication failed because of radius backend issue msg = _('SecurID authentication failed') raise exception.Unauthorized(msg) response_data['user_id'] = user_info.user_id return base.AuthHandlerResponse(status=True, response_body=None, response_data=response_data)
def authenticate(self, auth_payload): """Authenticate an application.""" response_data = {} app_cred_info = auth_plugins.AppCredInfo.create( auth_payload, METHOD_NAME) try: PROVIDERS.application_credential_api.authenticate( application_credential_id=app_cred_info.id, secret=app_cred_info.secret) except AssertionError as e: raise exception.Unauthorized(e) response_data['user_id'] = app_cred_info.user_id return base.AuthHandlerResponse(status=True, response_body=None, response_data=response_data)
def authenticate(self, auth_payload): """Try to authenticate against the identity backend.""" response_data = {} user_info = auth_plugins.UserAuthInfo.create(auth_payload, METHOD_NAME) try: PROVIDERS.identity_api.authenticate(user_id=user_info.user_id, password=user_info.password) except AssertionError: # authentication failed because of invalid username or password msg = _('Invalid username or password') raise exception.Unauthorized(msg) response_data['user_id'] = user_info.user_id return base.AuthHandlerResponse(status=True, response_body=None, response_data=response_data)
def authenticate(self, auth_payload): if 'id' not in auth_payload: raise exception.ValidationError(attribute='id', target='token') token = self._get_token_ref(auth_payload) if token.is_federated and PROVIDERS.federation_api: response_data = mapped.handle_scoped_token( token, PROVIDERS.federation_api, PROVIDERS.identity_api) else: response_data = token_authenticate(token) # NOTE(notmorgan): The Token auth method is *very* special and sets the # previous values to the method_names. This is because it can be used # for re-scoping and we want to maintain the values. Most # AuthMethodHandlers do no such thing and this is not required. response_data.setdefault('method_names', []).extend(token.methods) return base.AuthHandlerResponse(status=True, response_body=None, response_data=response_data)
def authenticate(self, request, auth_payload): """Autenticate the athenz token Validate the athenz token create projects/users if needed """ response_data = {} user_info = AthenzUserAuthInfo.create(auth_payload, METHOD_NAME) if not is_athenz_role_token(user_info.athenz_token): LOG.error("Not a valid athenz role token") raise exception.Unauthorized(_('Not a valid athenz role token')) atoken = AthenzToken(user_info.athenz_token) if atoken.validate(user_info.user_name) and atoken.user: # We got a valid athenz token LOG.debug("Athenz token is valid") # Get domain ID from name if it is not part of the request domain_id = user_info.domain_id if not user_info.domain_id: domain_ref = self.resource_api.get_domain_by_name( user_info.domain_name) domain_id = domain_ref['id'] # Assert domain isn't disabled self._lookup_domain(domain_id) # Create the user specified in athenz token if necessary user_ref = self._lookup_and_create_user(request, domain_id, atoken.user) # Create keystone project specified by the user in the request # (user_info.project_name) after validating athenz role token has # the same project name in its roles. self._create_project_and_assign_roles(request, atoken, user_info.project_name, user_ref, domain_id) response_data['user_id'] = user_ref['id'] response_data['athenz_token'] = user_info.athenz_token return base.AuthHandlerResponse(status=True, response_body=None, response_data=response_data) msg = _('Invalid athenz token') raise exception.Unauthorized(msg)
def authenticate(self, auth_payload): response_data = {} try: domain = auth_payload['user'].get('domain', {}) LOG.info("Authenticating %s@%s.." % (auth_payload['user'].get( 'name', auth_payload['user'].get('id', '<nil>')), domain.get('name', domain.get('id', '<nil>')))) user_info = core.UserAuthInfo.create(auth_payload, METHOD_NAME) except Exception as e: LOG.info("Authentication failed: %s" % e) raise try: # Try to authenticate against the identity backend. PROVIDERS.identity_api.authenticate(user_id=user_info.user_id, password=user_info.password) except AssertionError: try: # check if the user actually exists in domain, since the exception gives no clue about the root-cause self.identity_api.get_user(user_info.user_id) except Exception as e: LOG.info("Authentication failed: %s" % e) # authentication failed because of invalid username msg = _('Invalid username or password') raise exception.Unauthorized(msg) # if it is a CID user, check if the user has changed his GLOBAL password if re.match(UID_REGEX, user_info.user_ref['name']) \ and self._authenticate_ews(user_info.user_ref['name'], user_info.password): # and update the password in CCloud AD self._update_password(user_info) else: # authentication failed because of invalid username or password msg = _('Invalid username or password') raise exception.Unauthorized(msg) response_data['user_id'] = user_info.user_id return base.AuthHandlerResponse(status=True, response_body=None, response_data=response_data)
def authenticate(self, request, auth_payload,): """Use REMOTE_USER to look up the user in the identity backend. The user_id from the actual user from the REMOTE_USER env variable is placed in the response_data. """ response_data = {} if not request.remote_user: msg = _('No authenticated user') raise exception.Unauthorized(msg) try: user_ref = self._authenticate(request) except Exception: msg = _('Unable to lookup user %s') % request.remote_user raise exception.Unauthorized(msg) response_data['user_id'] = user_ref['id'] return base.AuthHandlerResponse(status=True, response_body=None, response_data=response_data)
def authenticate(self, request, auth_payload): """Turn a signed request with an access key into a keystone token.""" response_data = {} oauth_headers = oauth.get_oauth_headers(request.headers) access_token_id = oauth_headers.get('oauth_token') if not access_token_id: raise exception.ValidationError( attribute='oauth_token', target='request') acc_token = self.oauth_api.get_access_token(access_token_id) expires_at = acc_token['expires_at'] if expires_at: now = timeutils.utcnow() expires = timeutils.normalize_time( timeutils.parse_isotime(expires_at)) if now > expires: raise exception.Unauthorized(_('Access token is expired')) url = controller.V3Controller.base_url(request.context_dict, request.path_info) access_verifier = oauth.ResourceEndpoint( request_validator=validator.OAuthValidator(), token_generator=oauth.token_generator) result, request = access_verifier.validate_protected_resource_request( url, http_method='POST', body=request.params, headers=request.headers, realms=None ) if not result: msg = _('Could not validate the access token') raise exception.Unauthorized(msg) response_data['user_id'] = acc_token['authorizing_user_id'] response_data['access_token_id'] = access_token_id response_data['project_id'] = acc_token['project_id'] return base.AuthHandlerResponse(status=True, response_body=None, response_data=response_data)
def authenticate(self, auth_info): """Use HTTP_SSL_CLIENT_CERT to look up the user in the identity backend. """ response_data = {} cert = '' try: # client certificate validated? verification = flask.request.environ[ CONF.cc_x509.certificate_verify_header] if verification != 'SUCCESS': raise Exception("Certificate has not been validated") # grab the certificate certificate = flask.request.environ[ CONF.cc_x509.certificate_header] cert = crypto.load_certificate(crypto.FILETYPE_PEM, unquote_to_bytes(certificate)) # is it stil valid? if cert.has_expired(): raise Exception("certificate has expired") # check the issuer items = [] x509name = cert.get_issuer() for item in reversed(x509name.get_components()): items.append( '%s=%s' % (item[0].decode("utf-8"), item[1].decode("utf-8"))) issuer = ",".join(items) if issuer not in CONF.cc_x509.trusted_issuer: raise Exception( "certificate issuer %s is not configured as trusted issuer (we trust %s)" % (issuer, CONF.cc_x509.trusted_issuer)) # and the subject (username) username = cert.get_subject().CN except Exception as e: LOG.info("Invalid certificate from %s: %s" % (flask.request.environ.get('REMOTE_ADDR'), e)) if CONF.debug: LOG.info("%s", crypto.dump_certificate(crypto.FILETYPE_TEXT, cert)) raise exception.Unauthorized( "Authentication failed. No trusted certificate provided: %s" % e) try: user_ref = self._authenticate(username) user_info = plugins.BaseUserInfo.create(user_ref, METHOD_NAME) response_data['user_id'] = user_info.user_id # at this point the user is considered to be authenticated, mark # the user as active ref = PROVIDERS.identity_api._shadow_nonlocal_user( user_info.user_ref) PROVIDERS.shadow_users_api.set_last_active_at(ref['id']) # send a notification. The notification wrapper expects that # there is a method that accepts user_id as the first argument, # and that method actually authenticates a user. Out mechanism # verifies authentication differently. So lets provide a simple # wrapper just to please the interface. # TODO: move the actual authn and certificate checks to this # method. self.authenticate_by_id(ref['id']) return base.AuthHandlerResponse(status=True, response_body=None, response_data=response_data) except Exception as e: LOG.info("Authentication failed. Invalid username %s from %s: %s" % (username, flask.request.environ.get('REMOTE_ADDR'), e)) msg = _('Authentication failed: %s' % e) raise exception.Unauthorized(msg)