예제 #1
0
    def authenticate(self, context, auth=None):
        """Authenticate credentials and return a token.

        Accept auth as a dict that looks like::

            {
                "auth":{
                    "passwordCredentials":{
                        "username":"******",
                        "password":"******"
                    },
                    "tenantName":"customer-x"
                }
            }

        In this case, tenant is optional, if not provided the token will be
        considered "unscoped" and can later be used to get a scoped token.

        Alternatively, this call accepts auth with only a token and tenant
        that will return a token that is scoped to that tenant.
        """

        if auth is None:
            raise exception.ValidationError(attribute='auth',
                                            target='request body')

        auth_token_data = None

        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)

        user_ref, tenant_ref, metadata_ref, expiry = auth_info
        core.validate_auth_info(self, context, user_ref, tenant_ref)
        trust_id = metadata_ref.get('trust_id')
        user_ref = self._filter_domain_id(user_ref)
        if tenant_ref:
            tenant_ref = self._filter_domain_id(tenant_ref)
        auth_token_data = self._get_auth_token_data(user_ref, tenant_ref,
                                                    metadata_ref, expiry)

        if tenant_ref:
            catalog_ref = self.catalog_api.get_catalog(
                context=context,
                user_id=user_ref['id'],
                tenant_id=tenant_ref['id'],
                metadata=metadata_ref)
        else:
            catalog_ref = {}

        auth_token_data['id'] = 'placeholder'

        roles_ref = []
        for role_id in metadata_ref.get('roles', []):
            role_ref = self.identity_api.get_role(context, role_id)
            roles_ref.append(dict(name=role_ref['name']))

        token_data = Auth.format_token(auth_token_data, roles_ref)

        service_catalog = Auth.format_catalog(catalog_ref)
        token_data['access']['serviceCatalog'] = service_catalog

        if CONF.signing.token_format == 'UUID':
            token_id = uuid.uuid4().hex
        elif CONF.signing.token_format == 'PKI':
            try:
                token_id = cms.cms_sign_token(json.dumps(token_data),
                                              CONF.signing.certfile,
                                              CONF.signing.keyfile)
            except subprocess.CalledProcessError:
                raise exception.UnexpectedError(_('Unable to sign token.'))
        else:
            raise exception.UnexpectedError(
                _('Invalid value for token_format: %s.'
                  '  Allowed values are PKI or UUID.') %
                CONF.signing.token_format)
        try:
            self.token_api.create_token(
                context, token_id,
                dict(key=token_id,
                     id=token_id,
                     expires=auth_token_data['expires'],
                     user=user_ref,
                     tenant=tenant_ref,
                     metadata=metadata_ref,
                     trust_id=trust_id))
        except Exception as e:
            # an identical token may have been created already.
            # if so, return the token_data as it is also identical
            try:
                self.token_api.get_token(context=context, token_id=token_id)
            except exception.TokenNotFound:
                raise e

        token_data['access']['token']['id'] = token_id

        return token_data
예제 #2
0
    def authenticate(self, context, auth=None):
        """Authenticate credentials and return a token.

        Accept auth as a dict that looks like::

            {
                "auth":{
                    "passwordCredentials":{
                        "username":"******",
                        "password":"******"
                    },
                    "tenantName":"customer-x"
                }
            }

        In this case, tenant is optional, if not provided the token will be
        considered "unscoped" and can later be used to get a scoped token.

        Alternatively, this call accepts auth with only a token and tenant
        that will return a token that is scoped to that tenant.
        """

        if auth is None:
            raise exception.ValidationError(attribute='auth',
                                            target='request body')

        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)

        user_ref, tenant_ref, metadata_ref, expiry, bind = auth_info
        core.validate_auth_info(self, user_ref, tenant_ref)
        # NOTE(morganfainberg): Make sure the data is in correct form since it
        # might be consumed external to Keystone and this is a v2.0 controller.
        # The user_ref is encoded into the auth_token_data which is returned as
        # part of the token data. The token provider doesn't care about the
        # format.
        user_ref = self.v3_to_v2_user(user_ref)
        if tenant_ref:
            tenant_ref = self.filter_domain_id(tenant_ref)
        auth_token_data = self._get_auth_token_data(user_ref, tenant_ref,
                                                    metadata_ref, expiry)

        if tenant_ref:
            catalog_ref = self.catalog_api.get_catalog(user_ref['id'],
                                                       tenant_ref['id'],
                                                       metadata_ref)
        else:
            catalog_ref = {}

        auth_token_data['id'] = 'placeholder'
        if bind:
            auth_token_data['bind'] = bind

        roles_ref = []
        for role_id in metadata_ref.get('roles', []):
            role_ref = self.assignment_api.get_role(role_id)
            roles_ref.append(dict(name=role_ref['name']))

        (token_id, token_data) = self.token_provider_api.issue_v2_token(
            auth_token_data, roles_ref=roles_ref, catalog_ref=catalog_ref)
        return token_data
예제 #3
0
    def authenticate(self, context, auth=None):
        """Authenticate credentials and return a token.

        Accept auth as a dict that looks like::

            {
                "auth":{
                    "passwordCredentials":{
                        "username":"******",
                        "password":"******"
                    },
                    "tenantName":"customer-x"
                }
            }

        In this case, tenant is optional, if not provided the token will be
        considered "unscoped" and can later be used to get a scoped token.

        Alternatively, this call accepts auth with only a token and tenant
        that will return a token that is scoped to that tenant.
        """

        if auth is None:
            raise exception.ValidationError(attribute='auth',
                                            target='request body')

        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)

        user_ref, tenant_ref, metadata_ref, expiry, bind = auth_info
        core.validate_auth_info(self, user_ref, tenant_ref)
        # NOTE(morganfainberg): Make sure the data is in correct form since it
        # might be consumed external to Keystone and this is a v2.0 controller.
        # The user_ref is encoded into the auth_token_data which is returned as
        # part of the token data. The token provider doesn't care about the
        # format.
        user_ref = self.v3_to_v2_user(user_ref)
        if tenant_ref:
            tenant_ref = self.filter_domain_id(tenant_ref)
        auth_token_data = self._get_auth_token_data(user_ref,
                                                    tenant_ref,
                                                    metadata_ref,
                                                    expiry)

        if tenant_ref:
            catalog_ref = self.catalog_api.get_catalog(
                user_ref['id'], tenant_ref['id'], metadata_ref)
        else:
            catalog_ref = {}

        auth_token_data['id'] = 'placeholder'
        if bind:
            auth_token_data['bind'] = bind

        roles_ref = []
        for role_id in metadata_ref.get('roles', []):
            role_ref = self.assignment_api.get_role(role_id)
            roles_ref.append(dict(name=role_ref['name']))

        (token_id, token_data) = self.token_provider_api.issue_v2_token(
            auth_token_data, roles_ref=roles_ref, catalog_ref=catalog_ref)
        return token_data
예제 #4
0
    def authenticate(self, context, auth=None):
        """Authenticate credentials and return a token.

        Accept auth as a dict that looks like::

            {
                "auth":{
                    "passwordCredentials":{
                        "username":"******",
                        "password":"******"
                    },
                    "tenantName":"customer-x"
                }
            }

        In this case, tenant is optional, if not provided the token will be
        considered "unscoped" and can later be used to get a scoped token.

        Alternatively, this call accepts auth with only a token and tenant
        that will return a token that is scoped to that tenant.
        """

        if auth is None:
            raise exception.ValidationError(attribute='auth',
                                            target='request body')

        auth_token_data = None

        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)

        user_ref, tenant_ref, metadata_ref, expiry, bind = auth_info
        core.validate_auth_info(self, user_ref, tenant_ref)
        user_ref = self._filter_domain_id(user_ref)
        if tenant_ref:
            tenant_ref = self._filter_domain_id(tenant_ref)
        auth_token_data = self._get_auth_token_data(user_ref,
                                                    tenant_ref,
                                                    metadata_ref,
                                                    expiry)

        if tenant_ref:
            catalog_ref = self.catalog_api.get_catalog(
                user_ref['id'], tenant_ref['id'], metadata_ref)
        else:
            catalog_ref = {}

        auth_token_data['id'] = 'placeholder'
        if bind:
            auth_token_data['bind'] = bind

        roles_ref = []
        for role_id in metadata_ref.get('roles', []):
            role_ref = self.identity_api.get_role(role_id)
            roles_ref.append(dict(name=role_ref['name']))

        (token_id, token_data) = self.token_provider_api.issue_v2_token(
            auth_token_data, roles_ref=roles_ref, catalog_ref=catalog_ref)
        return token_data
예제 #5
0
    def authenticate(self, context, auth=None):
        """Authenticate credentials and return a token.

        Accept auth as a dict that looks like::

            {
                "auth":{
                    "passwordCredentials":{
                        "username":"******",
                        "password":"******"
                    },
                    "tenantName":"customer-x"
                }
            }

        In this case, tenant is optional, if not provided the token will be
        considered "unscoped" and can later be used to get a scoped token.

        Alternatively, this call accepts auth with only a token and tenant
        that will return a token that is scoped to that tenant.
        """

        if auth is None:
            raise exception.ValidationError(attribute='auth',
                                            target='request body')

        auth_token_data = None

        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)

        user_ref, tenant_ref, metadata_ref, expiry = auth_info
        core.validate_auth_info(self, context, user_ref, tenant_ref)
        trust_id = metadata_ref.get('trust_id')
        user_ref = self._filter_domain_id(user_ref)
        if tenant_ref:
            tenant_ref = self._filter_domain_id(tenant_ref)
        auth_token_data = self._get_auth_token_data(user_ref,
                                                    tenant_ref,
                                                    metadata_ref,
                                                    expiry)

        if tenant_ref:
            catalog_ref = self.catalog_api.get_catalog(
                context=context,
                user_id=user_ref['id'],
                tenant_id=tenant_ref['id'],
                metadata=metadata_ref)
        else:
            catalog_ref = {}

        auth_token_data['id'] = 'placeholder'

        roles_ref = []
        for role_id in metadata_ref.get('roles', []):
            role_ref = self.identity_api.get_role(context, role_id)
            roles_ref.append(dict(name=role_ref['name']))

        token_data = Auth.format_token(auth_token_data, roles_ref)

        service_catalog = Auth.format_catalog(catalog_ref)
        token_data['access']['serviceCatalog'] = service_catalog

        if CONF.signing.token_format == 'UUID':
            token_id = uuid.uuid4().hex
        elif CONF.signing.token_format == 'PKI':
            try:
                token_id = cms.cms_sign_token(json.dumps(token_data),
                                              CONF.signing.certfile,
                                              CONF.signing.keyfile)
            except environment.subprocess.CalledProcessError:
                raise exception.UnexpectedError(_(
                    'Unable to sign token.'))
        else:
            raise exception.UnexpectedError(_(
                'Invalid value for token_format: %s.'
                '  Allowed values are PKI or UUID.') %
                CONF.signing.token_format)
        try:
            self.token_api.create_token(
                context, token_id, dict(key=token_id,
                                        id=token_id,
                                        expires=auth_token_data['expires'],
                                        user=user_ref,
                                        tenant=tenant_ref,
                                        metadata=metadata_ref,
                                        trust_id=trust_id))
        except Exception as e:
            # an identical token may have been created already.
            # if so, return the token_data as it is also identical
            try:
                self.token_api.get_token(context=context,
                                         token_id=token_id)
            except exception.TokenNotFound:
                raise e

        token_data['access']['token']['id'] = token_id

        return token_data
예제 #6
0
    def authenticate(self, context, auth=None):
        """Authenticate credentials and return a token.

        Accept auth as a dict that looks like::

            {
                "auth":{
                    "passwordCredentials":{
                        "username":"******",
                        "password":"******"
                    },
                    "tenantName":"customer-x"
                }
            }

        In this case, tenant is optional, if not provided the token will be
        considered "unscoped" and can later be used to get a scoped token.

        Alternatively, this call accepts auth with only a token and tenant
        that will return a token that is scoped to that tenant.
        """

        if auth is None:
            raise exception.ValidationError(attribute='auth',
                                            target='request body')

        auth_token_data = None

        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)

        user_ref, tenant_ref, metadata_ref, expiry, bind = auth_info
        core.validate_auth_info(self, user_ref, tenant_ref)
        user_ref = self._filter_domain_id(user_ref)
        if tenant_ref:
            tenant_ref = self._filter_domain_id(tenant_ref)
        auth_token_data = self._get_auth_token_data(user_ref,
                                                    tenant_ref,
                                                    metadata_ref,
                                                    expiry)

        if tenant_ref:
            catalog_ref = self.catalog_api.get_catalog(
                user_id=user_ref['id'],
                tenant_id=tenant_ref['id'],
                metadata=metadata_ref)
        else:
            catalog_ref = {}

        auth_token_data['id'] = 'placeholder'
        if bind:
            auth_token_data['bind'] = bind

        roles_ref = []
        for role_id in metadata_ref.get('roles', []):
            role_ref = self.identity_api.get_role(role_id)
            roles_ref.append(dict(name=role_ref['name']))

        (token_id, token_data) = self.token_provider_api.issue_token(
            version=token_provider.V2,
            token_ref=auth_token_data,
            roles_ref=roles_ref,
            catalog_ref=catalog_ref)
        return token_data