← Back to team overview

yahoo-eng-team team mailing list archive

[Bug 1461728] Re: V2.0 API not calling defined external auth

 

As far as I can tell, and if i recall correctly, the V2.0 authentication
mechanisms do not use the plugins at all. The external authentication is
handled by keystone.token.controller.Auth._authenticate_external (
https://github.com/openstack/keystone/blob/943bbc11c5610f17ecee3b62e7d699a9c6676840/keystone/token/controllers.py#L318
). As you can see if you look into this code (and the rest of the V2
Auth) we don't call out to the auth plugins. auth plugins are a V3-only
construct.

As V2.0 is frozen, unless this is demonstrably a security risk - it is
not scheduled to be fixed. External Authentication should only occur if
the REMOTE_USER environment var is set, this is something that is
usually set by the apache module that is handling the external auth. The
simplest solution is to not allow external auth on the v2.0 interface
(http://<keystone host>:< keystone port>/v2.0/tokens ) and instead only
allow it on V3. This should prevent issues where the remote
authentication is not performed - as the REMOTE_USER variable will not
be set on the request.

REMOTE_USER should not be accepted from the user's request but should
only be set from (for example) mod_auth_kerb5.

Accepting REMOTE_USER from the user's request is a security flaw, but is
not what "external auth" is meant to address in Keystone. It seems to me
that you're looking for a custom auth plugin, which does a different
type of auth, not hooking into the apache/httpd/etc REMOTE_USER
variable.

** Changed in: keystone
       Status: New => Won't Fix

-- 
You received this bug notification because you are a member of Yahoo!
Engineering Team, which is subscribed to Keystone.
https://bugs.launchpad.net/bugs/1461728

Title:
  V2.0 API not calling defined external auth

Status in OpenStack Identity (Keystone):
  Won't Fix
Status in OpenStack Security Advisories:
  Incomplete

Bug description:
  When keystone.conf is defined with external auth , all V2.0 API calls
  do not get intercepted by the defined external auth.

  this is my keystone.conf
  [auth]
  methods=password,token,external
  external=keystone.auth.plugins.idm_external.IDMDefaultDomain

  V.20 CURL to initiate external auth.
  curl -X POST -d '{"auth":{}}' -H "Content-type: application/json" -H "REMOTE_USER: admin" http://localhost:5000/v2.0/tokens

  What I'm seeing is the call gets to the keystone/token/controller.py,
  where it checks for the auth{} and executes the external
  authentication

          if "token" in auth:
              # Try to authenticate using a token
              auth_info = self._authenticate_token(
                  context, auth)
          else:
              # Try external authentication
              try:
                  auth_info = self._authenticate_external(
                      context, auth)
              except ExternalAuthNotApplicable:
                  # Try local authentication
                  auth_info = self._authenticate_local(
                      context, auth)

  ...
     def _authenticate_external(self, context, auth):
          """Try to authenticate an external user via REMOTE_USER variable.

          Returns auth_token_data, (user_ref, tenant_ref, metadata_ref)
          """
          if 'REMOTE_USER' not in context.get('environment', {}):
              raise ExternalAuthNotApplicable()

          #NOTE(jamielennox): xml and json differ and get confused about what
          # empty auth should look like so just reset it.
          if not auth:
              auth = {}

          username = context['environment']['REMOTE_USER']
          try:
              user_ref = self.identity_api.get_user_by_name(
                  username, CONF.identity.default_domain_id)
              user_id = user_ref['id']
          except exception.UserNotFound as e:
              raise exception.Unauthorized(e)

          metadata_ref = {}
          tenant_id = self._get_project_id_from_auth(auth)
          tenant_ref, metadata_ref['roles'] = self._get_project_roles_and_ref(
              user_id, tenant_id)

          expiry = core.default_expire_time()
          bind = None
          if ('kerberos' in CONF.token.bind and
                  context['environment'].
                  get('AUTH_TYPE', '').lower() == 'negotiate'):
              bind = {'kerberos': username}

          return (user_ref, tenant_ref, metadata_ref, expiry, bind)

  The  _authenticate_external should not assume and have its own
  REMOTE_USER implementation,  instead it should look for the external
  method defined in keystone.conf and appropriately call the defined
  external class.

  The V3 call works fine and calls the right external class defined.
  curl -X POST -d '{"auth":{"identity":{"methods":["external"],"external":{}}}}'  -H "REMOTE_USER:admin" -H "Content-type: application/json" http://localhost:5000/v3/auth/tokens

  This is potentially a security hole as well, which will allow all V2
  API's to get Keystone token w/o password.

To manage notifications about this bug go to:
https://bugs.launchpad.net/keystone/+bug/1461728/+subscriptions