zoukankan      html  css  js  c++  java
  • Openstack Horizon and Django Compare the Working of authentication (Login)

    horizon的登陆流程 ,一直没看懂  后来看到了这篇blog 才恍然大悟~~~ 感叹对django的了解还不是很深啊~~~

    http://fosshelp.blogspot.com/2014/01/openstack-horizon-and-django-compare.html

    copy:

    Working of authentication (Login) in django
    ==============================================

    1)
    site-packages/django/contrib/auth/forms.py

    from django.contrib.auth import authenticate

    class AuthenticationForm(forms.Form):
        def clean(self):
            username = self.cleaned_data.get('username')
            password = self.cleaned_data.get('password')

            if username and password:
                self.user_cache = authenticate(username=username,
                                               password=password)


    2)
    ./openstack_dashboard/settings.py

    AUTHENTICATION_BACKENDS = ('openstack_auth.backend.KeystoneBackend',)

    3)
    site-packages/django/contrib/auth/__init__.py

    def get_backends():
        from django.conf import settings
        backends = []
        for backend_path in settings.AUTHENTICATION_BACKENDS:
            backends.append(load_backend(backend_path))

        if not backends:
            raise ImproperlyConfigured('No authentication backends have been defined. Does AUTHENTICATION_BACKENDS contain anything?')
        return backends

    def authenticate(**credentials):
        """
        If the given credentials are valid, return a User object.
        """
        for backend in get_backends():
            try:
                user = backend.authenticate(**credentials)
            except TypeError:
                # This backend doesn't accept these credentials as arguments. Try the next one.
                continue
            if user is None:
                continue
            # Annotate the user object with the path of the backend.
            user.backend = "%s.%s" % (backend.__module__, backend.__class__.__name__)
            return user

        # The credentials supplied are invalid to all backends, fire signal
        user_login_failed.send(sender=__name__,
                credentials=_clean_credentials(credentials))


    Working of authentication (Login) in Horizon
    ==============================================

    1a)
    horizon/openstack_dashboard/views.py

    from openstack_auth import views

    @vary.vary_on_cookie
    def splash(request):
        if request.user.is_authenticated():
            return shortcuts.redirect(get_user_home(request.user))
        form = views.Login(request)
        request.session.clear()
        request.session.set_test_cookie()
        return shortcuts.render(request, 'splash.html', {'form': form})

    1b)
    site-packages/openstack_auth/views.py

    from django.contrib.auth.views import login as django_login
    from .forms import Login

    def login(request):
        initial = {}
        current_region = request.session.get('region_endpoint', None)
        requested_region = request.GET.get('region', None)
        regions = dict(getattr(settings, "AVAILABLE_REGIONS", []))
        if requested_region in regions and requested_region != current_region:
            initial.update({'region': requested_region})

        if request.method == "POST":
            form = curry(Login, request)
        else:
            form = curry(Login, initial=initial)


        extra_context = {'redirect_field_name': REDIRECT_FIELD_NAME}

        if request.is_ajax():
            template_name = 'auth/_login.html'
            extra_context['hide'] = True
        else:
            template_name = 'auth/login.html'

        res = django_login(request,
                           template_name=template_name,
                           authentication_form=form,
                           extra_context=extra_context)
        # Set the session data here because django's session key rotation
        # will erase it if we set it earlier.
        if request.user.is_authenticated():
            set_session_from_user(request, request.user)
            regions = dict(Login.get_region_choices())
            region = request.user.endpoint
            region_name = regions.get(region)
            request.session['region_endpoint'] = region
            request.session['region_name'] = region_name
        return res

    1c)
    site-packages/django/contrib/auth/views.py

    def login(request, template_name='registration/login.html',
              redirect_field_name=REDIRECT_FIELD_NAME,
              authentication_form=AuthenticationForm,
              current_app=None, extra_context=None):

        ////blabla////
        return TemplateResponse(request, template_name, context,
                                current_app=current_app)


    1d)
    site-packages/openstack_auth/forms.py

    from django.contrib.auth import authenticate

    class Login(AuthenticationForm):
        region = forms.ChoiceField(label=_("Region"), required=False)
        username = forms.CharField(label=_("User Name"))
        password = forms.CharField(label=_("Password"),
                                   widget=forms.PasswordInput(render_value=False))

        def clean(self):
            default_domain = getattr(settings,
                                     'OPENSTACK_KEYSTONE_DEFAULT_DOMAIN',
                                     'Default')
            username = self.cleaned_data.get('username')
            password = self.cleaned_data.get('password')
            region = self.cleaned_data.get('region')
            domain = self.cleaned_data.get('domain', default_domain)

            if not (username and password):
                # Don't authenticate, just let the other validators handle it.
                return self.cleaned_data

            try:
                self.user_cache = authenticate(request=self.request,
                                               username=username,
                                               password=password,
                                               user_domain_name=domain,
                                               auth_url=region)

                msg = 'Login successful for user "%(username)s".' %
                    {'username': username}
                LOG.info(msg)
            except KeystoneAuthException as exc:
                msg = 'Login failed for user "%(username)s".' %
                    {'username': username}
                LOG.warning(msg)
                self.request.session.flush()
                raise forms.ValidationError(exc)
            self.check_for_test_cookie()
            return self.cleaned_data

    2)
    Same as in django


    3)
    Same as in django


    4)
    site-packages/openstack_auth/backend.py

    from .user import create_user_from_token
    from .user import Token

    from .utils import check_token_expiration
    from .utils import get_keystone_client

    class KeystoneBackend(object):

        def authenticate(self, request=None, username=None, password=None,
                         user_domain_name=None, auth_url=None):

            """Authenticates a user via the Keystone Identity API. """
            LOG.debug('Beginning user authentication for user "%s".' % username)

            insecure = getattr(settings, 'OPENSTACK_SSL_NO_VERIFY', False)
            endpoint_type = getattr(
                settings, 'OPENSTACK_ENDPOINT_TYPE', 'publicURL')

            keystone_client = get_keystone_client()
            try:
                client = keystone_client.Client(
                    user_domain_name=user_domain_name,
                    username=username,
                    password=password,
                    auth_url=auth_url,
                    insecure=insecure,
                    debug=settings.DEBUG)


                unscoped_auth_ref = client.auth_ref
                unscoped_token = Token(auth_ref=unscoped_auth_ref)
            except (keystone_exceptions.Unauthorized,
                    keystone_exceptions.Forbidden,
                    keystone_exceptions.NotFound) as exc:
                msg = _('Invalid user name or password.')
                LOG.debug(exc.message)
                raise KeystoneAuthException(msg)
            except (keystone_exceptions.ClientException,
                    keystone_exceptions.AuthorizationFailure) as exc:
                msg = _("An error occurred authenticating. "
                        "Please try again later.")
                LOG.debug(exc.message)
                raise KeystoneAuthException(msg)

            # Check expiry for our unscoped auth ref.
            self.check_auth_expiry(unscoped_auth_ref)

            # Check if token is automatically scoped to default_project
            if unscoped_auth_ref.project_scoped:
                auth_ref = unscoped_auth_ref
            else:
                # For now we list all the user's projects and iterate through.
                try:
                    if get_keystone_version() < 3:
                        projects = client.tenants.list()
                    else:
                        client.management_url = auth_url
                        projects = client.projects.list(
                            user=unscoped_auth_ref.user_id)
                except (keystone_exceptions.ClientException,
                        keystone_exceptions.AuthorizationFailure) as exc:
                    msg = _('Unable to retrieve authorized projects.')
                    raise KeystoneAuthException(msg)

                # Abort if there are no projects for this user
                if not projects:
                    msg = _('You are not authorized for any projects.')
                    raise KeystoneAuthException(msg)

                while projects:
                    project = projects.pop()
                    try:
                        client = keystone_client.Client(
                            tenant_id=project.id,
                            token=unscoped_auth_ref.auth_token,
                            auth_url=auth_url,
                            insecure=insecure,
                            debug=settings.DEBUG)
                        auth_ref = client.auth_ref
                        break
                    except (keystone_exceptions.ClientException,
                            keystone_exceptions.AuthorizationFailure):
                        auth_ref = None

                if auth_ref is None:
                    msg = _("Unable to authenticate to any available projects.")
                    raise KeystoneAuthException(msg)

            # Check expiry for our new scoped token.
            self.check_auth_expiry(auth_ref)

            # If we made it here we succeeded. Create our User!
            user = create_user_from_token(
                request,
                Token(auth_ref),
                client.service_catalog.url_for(endpoint_type=endpoint_type))


            if request is not None:
                request.session['unscoped_token'] = unscoped_token.id
                request.user = user

                # Support client caching to save on auth calls.
                setattr(request, KEYSTONE_CLIENT_ATTR, client)

            LOG.debug('Authentication completed for user "%s".' % username)
            return user

  • 相关阅读:
    js或jQuery获取当前屏幕的各种高度
    js简单时间比较的方法(转)
    取值:form表单取值、input框绑定取值
    Json对象与Json字符串的转化、JSON字符串与Java对象的转换(转)
    js 小数取整的函数
    (转)js数组与字符串的相互转换方法
    (转)js在数组中删除重复的元素自保留一个(两种实现思路)
    (转载)jQuery判断checkbox是否选中的3种方法(个人用第二种方法)
    (转载)jquery实现全选、反选、获得所有选中的checkbox
    JSP 服务器响应
  • 原文地址:https://www.cnblogs.com/Jghost/p/3660164.html
Copyright © 2011-2022 走看看