【问题标题】:Using django-cas-ng to authenticate on admin site使用 django-cas-ng 在管理站点上进行身份验证
【发布时间】:2018-08-02 11:25:42
【问题描述】:

我正在使用django-cas-ng 框架对用户进行身份验证。主要问题是管理页面仍然使用默认的登录视图。

目前使用的方法:

1.- 使用环境变量

来自文档:

CAS_ADMIN_PREFIX:Django 管理站点的 URL 前缀。如果未定义,CAS 中间件将检查正在呈现的视图以查看它是否位于 django.contrib.admin.views 中。


2.- 在 app/urls.py 上重定向 url:

url(r'^arta/admin/login$',  django_cas_ng.views.login, name='cas_ng_login')

一切都被忽略,并显示管理员登录表单。

这样做的目的是仅通过 CAS 进行身份验证并将当前的 /app/admin/login 重定向到 CAS

【问题讨论】:

    标签: python django cas


    【解决方案1】:

    如果有人对答案感兴趣,则解决方案是覆盖 AdminSite。 Django 管理模块覆盖了它自己的 url 重定向,所以在 /app/urls.py 上编辑它们是没有用的。

    创建一个 /app/admin.py 并扩展 AdminSite,例如:

    from django.contrib.admin import AdminSite
    from functools import update_wrapper
    from django.urls import NoReverseMatch, reverse
    from django.views.decorators.cache import never_cache
    from django.views.decorators.csrf import csrf_protect
    from django.http import Http404, HttpResponseRedirect
    import django_cas_ng.views
    
    
    class Admin(AdminSite):
        def admin_view(self, view, cacheable=False):
            """
            Decorator to create an admin view attached to this ``AdminSite``. This
            wraps the view and provides permission checking by calling
            ``self.has_permission``.
    
            You'll want to use this from within ``AdminSite.get_urls()``:
    
                class MyAdminSite(AdminSite):
    
                    def get_urls(self):
                        from django.conf.urls import url
    
                        urls = super(MyAdminSite, self).get_urls()
                        urls += [
                            url(r'^my_view/$', self.admin_view(some_view))
                        ]
                        return urls
    
            By default, admin_views are marked non-cacheable using the
            ``never_cache`` decorator. If the view can be safely cached, set
            cacheable=True.
            """
            def inner(request, *args, **kwargs):
                if not self.has_permission(request):
                    if request.path == reverse('cas_ng_logout', current_app=self.name):
                        index_path = reverse('admin:index', current_app=self.name)
                        return HttpResponseRedirect(index_path)
                    # Inner import to prevent django.contrib.admin (app) from
                    # importing django.contrib.auth.models.User (unrelated model).
                    from django.contrib.auth.views import redirect_to_login
                    return redirect_to_login(
                        request.get_full_path(),
                        reverse('cas_ng_login', current_app=self.name)
                    )
                return view(request, *args, **kwargs)
            if not cacheable:
                inner = never_cache(inner)
            # We add csrf_protect here so this function can be used as a utility
            # function for any view, without having to repeat 'csrf_protect'.
            if not getattr(view, 'csrf_exempt', False):
                inner = csrf_protect(inner)
            return update_wrapper(inner, view)
    
        def get_urls(self):
            from django.conf.urls import url, include
            # Since this module gets imported in the application's root package,
            # it cannot import models from other applications at the module level,
            # and django.contrib.contenttypes.views imports ContentType.
            from django.contrib.contenttypes import views as contenttype_views
    
            def wrap(view, cacheable=False):
                def wrapper(*args, **kwargs):
                    return self.admin_view(view, cacheable)(*args, **kwargs)
                wrapper.admin_site = self
                return update_wrapper(wrapper, view)
    
            # Admin-site-wide views.
            urlpatterns = [
                url(r'^$', wrap(self.index), name='index'),
                url(r'^login/$', django_cas_ng.views.login, name='login'),
                url(r'^logout/$', django_cas_ng.views.logout, name='logout'),
                url(r'^password_change/$', wrap(self.password_change, cacheable=True), name='password_change'),
                url(r'^password_change/done/$', wrap(self.password_change_done, cacheable=True),
                    name='password_change_done'),
                url(r'^jsi18n/$', wrap(self.i18n_javascript, cacheable=True), name='jsi18n'),
                url(r'^r/(?P<content_type_id>\d+)/(?P<object_id>.+)/$', wrap(contenttype_views.shortcut),
                    name='view_on_site'),
            ]
    
            # Add in each model's views, and create a list of valid URLS for the
            # app_index
            valid_app_labels = []
            for model, model_admin in self._registry.items():
                urlpatterns += [
                    url(r'^%s/%s/' % (model._meta.app_label, model._meta.model_name), include(model_admin.urls)),
                ]
                if model._meta.app_label not in valid_app_labels:
                    valid_app_labels.append(model._meta.app_label)
    
            # If there were ModelAdmins registered, we should have a list of app
            # labels for which we need to allow access to the app_index view,
            if valid_app_labels:
                regex = r'^(?P<app_label>' + '|'.join(valid_app_labels) + ')/$'
                urlpatterns += [
                    url(regex, wrap(self.app_index), name='app_list'),
                ]
            return urlpatterns
    
    site = Admin()
    

    然后你重写你想要的方法,在本例中是 admin_viewget_urls

    有趣的几行是:

    admin_view

     if request.path == reverse('cas_ng_logout', current_app=self.name):
     ----
     reverse('cas_ng_login', current_app=self.name)
    

    get_urls

    url(r'^login/$', django_cas_ng.views.login, name='login'),
    url(r'^logout/$', django_cas_ng.views.logout, name='logout')
    

    这将使您将登录和注销步骤重定向到 CAS

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-20
      • 1970-01-01
      • 1970-01-01
      • 2016-03-24
      • 2014-09-06
      相关资源
      最近更新 更多