GVKun编程网logo

如何在基于 django 类的视图上使用 permission_required 装饰器(django界面设计)

4

对于想了解如何在基于django类的视图上使用permission_required装饰器的读者,本文将提供新的信息,我们将详细介绍django界面设计,并且为您提供关于@login_required

对于想了解如何在基于 django 类的视图上使用 permission_required 装饰器的读者,本文将提供新的信息,我们将详细介绍django界面设计,并且为您提供关于@login_required之后的Django重定向到下一个、@requirespermissions 无效问题原因、@RequiresPermissions 解释、Apache Shiro 使用 RequiresPermissions with Spring...的有价值信息。

本文目录一览:

如何在基于 django 类的视图上使用 permission_required 装饰器(django界面设计)

如何在基于 django 类的视图上使用 permission_required 装饰器(django界面设计)

我在理解新的 CBV 的工作原理时遇到了一些麻烦。我的问题是,我需要登录所有视图,其中一些视图需要特定权限。在基于函数的视图中,我使用
@permission_required() 和视图中的 login_required 属性来执行此操作,但我不知道如何在新视图上执行此操作。django
文档中是否有一些部分对此进行了解释?我什么也没找到。我的代码有什么问题?

我尝试使用@method_decorator,但它回复“ TypeError at /spaces/prueba/_wrapped_view()
需要至少 1 个参数(给定 0)

这是代码(GPL):

from django.utils.decorators import method_decoratorfrom django.contrib.auth.decorators import login_required, permission_requiredclass ViewSpaceIndex(DetailView):    """    Show the index page of a space. Get various extra contexts to get the    information for that space.    The get_object method searches in the user ''spaces'' field if the current    space is allowed, if not, he is redirected to a ''nor allowed'' page.     """    context_object_name = ''get_place''    template_name = ''spaces/space_index.html''    @method_decorator(login_required)    def get_object(self):        space_name = self.kwargs[''space_name'']        for i in self.request.user.profile.spaces.all():            if i.url == space_name:                return get_object_or_404(Space, url = space_name)        self.template_name = ''not_allowed.html''        return get_object_or_404(Space, url = space_name)    # Get extra context data    def get_context_data(self, **kwargs):        context = super(ViewSpaceIndex, self).get_context_data(**kwargs)        place = get_object_or_404(Space, url=self.kwargs[''space_name''])        context[''entities''] = Entity.objects.filter(space=place.id)        context[''documents''] = Document.objects.filter(space=place.id)        context[''proposals''] = Proposal.objects.filter(space=place.id).order_by(''-pub_date'')        context[''publication''] = Post.objects.filter(post_space=place.id).order_by(''-post_pubdate'')        return context

答案1

小编典典

CBV 文档中列出了一些策略:

urls.py在( [docs](https://docs.djangoproject.com/en/dev/topics/class-

based-views/intro/#decorating-in-urlconf) )中实例化视图时装饰视图

urlpatterns = [    path(''view/'',login_required(ViewSpaceIndex.as_view(..)),    ...]

urls.py装饰器是基于每个实例应用的,因此您可以根据需要在不同的路由中添加或删除它。

装饰您的类,以便包装视图的每个实例([文档](https://docs.djangoproject.com/en/dev/topics/class-

based-views/intro/#decorating-the-class))

有两种方法可以做到这一点:

  1. 适用method_decorator于您的 CBV 调度方法,例如,

     from django.utils.decorators import method_decorator

    from django.contrib.auth.decorators import login_required

    @method_decorator(login_required, name=’dispatch’)
    class ViewSpaceIndex(TemplateView):
    template_name = ‘secret.html’

如果您使用的是 Django <
1.9(您不应该这样做,它不再受支持),则您不能method_decorator在该类上使用,因此您必须dispatch手动覆盖该方法:

    class ViewSpaceIndex(TemplateView):        @method_decorator(login_required)        def dispatch(self, *args, **kwargs):            return super(ViewSpaceIndex, self).dispatch(*args, **kwargs)
  1. 使用像django.contrib.auth.mixins.LoginRequiredMixin这样的 mixin ,在此处的其他答案中得到了很好的概述:

     from django.contrib.auth.mixins import LoginRequiredMixin

    class MyView(LoginRequiredMixin, View):

     login_url = ''/login/'' redirect_field_name = ''redirect_to''

确保将 mixin 类放在继承列表的第一个位置(因此 Python
的方法解析顺序算法会选择正确的东西)。

您获得 a 的原因TypeError在文档中进行了解释:

注意:method_decorator 将 args 和 *kwargs 作为参数传递给类上的装饰方法。如果您的方法不接受一组兼容的参数,它将引发
TypeError 异常。

@login_required之后的Django重定向到下一个

@login_required之后的Django重定向到下一个

我觉得这是一个简单的问题,我只想走一小步。

我想执行以下任意操作(作为下一个参数中的术语):

[not signed in] -> profile -> login?next=/accounts/profile/ -> auth -> profile.[not signed in] -> newsfeed -> login?next=/newsfeed/` -> auth -> newsfeed.

而我目前要去的是:

[not signed in] -> profile -> login?next=/accounts/profile/ -> auth -> loggedin[not signed in] -> newsfeed -> login?next=/newsfeed/ -> auth -> loggedin

我正在寻找以某种方式将next参数从表单传递loginauthauth重定向到该参数的方法

目前,我正在尝试login.html

<input type=''text'' name="next" value="{{ next }}">

但是,这没有得到下一个值。我可以从调试工具栏中看到:

GET dataVariable    Valueu''next''     [u''/accounts/profile/'']

views

def auth_view(request):  username = request.POST.get(''username'', '''')  password = request.POST.get(''password'', '''')  user = auth.authenticate(username=username, password=password)  if user is not None:    auth.login(request, user)    print request.POST    return HttpResponseRedirect(request.POST.get(''next''),''/accounts/loggedin'')  else:    return HttpResponseRedirect(''/accounts/invalid'')

login.html

{% extends "base.html" %}{% block content %}  {% if form.errors %}  <p> Sorry, you have entered an incorrect username or password</p>  {% endif %}  <form action="/accounts/auth/" method="post">{% csrf_token %}    <label for="username">User name:</label>    <input type="text" name="username" value="" id="username">    <label for="password">Password:</label>    <input type="password" name="password" value="" id="password">    <input type=''text'' name="next" value="{{ request.GET.next }}">    <input type="submit" value="login">  </form>{% endblock %}

settings

from django.conf.urls import patterns, include, urlfrom django.contrib import adminadmin.autodiscover()urlpatterns = patterns('''',    # Examples:    url(r''^admin/'', include(admin.site.urls)),    (''^accounts/'', include(''userprofile.urls'')),    url(r''^accounts/login/$'', ''django_yunite.views.login''),    url(r''^accounts/auth/$'', ''django_yunite.views.auth_view''),    url(r''^accounts/logout/$'', ''django_yunite.views.logout''),    url(r''^accounts/loggedin/$'', ''django_yunite.views.loggedin''),    url(r''^accounts/invalid/$'', ''django_yunite.views.invalid_login''),)

settings

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)import osBASE_DIR = os.path.dirname(os.path.dirname(__file__))# SECURITY WARNING: don''t run with debug turned on in production!DEBUG = TrueTEMPLATE_DEBUG = TrueALLOWED_HOSTS = []# Application definitionINSTALLED_APPS = (    ''django.contrib.admin'',    ''django.contrib.auth'',    ''django.contrib.contenttypes'',    ''django.contrib.sessions'',    ''django.contrib.messages'',    ''django.contrib.staticfiles'',    ''debug_toolbar'',    ''userprofile'',)MIDDLEWARE_CLASSES = (    ''django.contrib.sessions.middleware.SessionMiddleware'',    ''django.middleware.common.CommonMiddleware'',    ''django.middleware.csrf.CsrfViewMiddleware'',    ''django.contrib.auth.middleware.AuthenticationMiddleware'',    ''django.contrib.messages.middleware.MessageMiddleware'',    ''django.middleware.clickjacking.XFrameOptionsMiddleware'',)ROOT_URLCONF = ''django_yunite.urls''WSGI_APPLICATION = ''django_yunite.wsgi.application''# Internationalization# https://docs.djangoproject.com/en/1.6/topics/i18n/LANGUAGE_CODE = ''en-ca''TIME_ZONE = ''EST''USE_I18N = TrueUSE_L10N = TrueUSE_TZ = True# Static files (CSS, JavaScript, Images)# https://docs.djangoproject.com/en/1.6/howto/static-files/STATIC_URL = ''/static/''STATICFILES_DIRS = (    (''assets'', ''/home/user/GitHub/venv_yunite/django_yunite/static/''),    )TEMPLATE_DIRS = (    ''./templates'',    ''/article/templates'',)STATIC_ROOT = "/home/user/Documents/static/"AUTH_PROFILE_MODULE = ''userprofile.UserProfile''

打印语句显示为空 u''next''

答案1

小编典典

查询字符串将隐式传递到任何视图,而无需编写任何特殊代码。

您要做的就是确保将next密钥从实际的登录表单(在您的情况下,这是在中呈现的表单/accounts/login/)传递到/accounts/auth视图。

为此,您需要确保django.core.context_processors.request在设置中启用了请求模板上下文处理器()。为此,首先需要导入的默认值TEMPLATE_CONTEXT_PROCESSORS,然后在中将请求处理器添加到其中settings.py,如下所示:

from django.conf import global_settingsTEMPLATE_CONTEXT_PROCESSORS = global_settings.TEMPLATE_CONTEXT_PROCESSORS + (    "django.core.context_processors.request",)

然后以以下形式:

<form method="POST" action="/accounts/auth">    {% csrf_token %}    <input type="hidden" name="next" value="{{ request.GET.next }}" />    {{ login_form }}    <input type="submit"></form>

现在,在您/accounts/auth看来:

def foo(request):    if request.method == ''POST'':        # .. authenticate your user        # redirect to the value of next if it is entered, otherwise        # to /accounts/profile/        return redirect(request.POST.get(''next'',''/accounts/profile/''))

@requirespermissions 无效问题原因

@requirespermissions 无效问题原因

给角色赋予了权限,放在Controller里无效

@RequestMapping(value = "/save",method = RequestMethod.GET)
@RequiresPermissions("test:save")
public String toSave(){
    return "/test/add";
}

但是,放在service里有效,会提示报,没有权限错误

org.apache.shiro.authz.UnauthorizedException: Subject does not have permission [test:save]

产生原因是因为拦截在 spring 容器中,而不是拦截在springMVC容器中,所以才会注解无效。

要在 springMVC 的配置文件里最上方进进行配置

注意:

不要在spring的配置里面进行配置

不要在spring的配置里面进行配置

不要在spring的配置里面进行配置

<beandepends-on="lifecycleBeanPostProcessor" />
<bean>
    <property name="securityManager" ref="securityManager" />
</bean>

 

@RequiresPermissions 解释

@RequiresPermissions 解释

@RequiresAuthentication

验证用户是否登录,等同于方法subject.isAuthenticated() 结果为true时。

@RequiresUser

验证用户是否被记忆,user有两种含义:

一种是成功登录的(subject.isAuthenticated() 结果为true);

另外一种是被记忆的(subject.isRemembered()结果为true)。

@RequiresGuest

验证是否是一个guest的请求,与@RequiresUser完全相反。

 换言之,RequiresUser  == !RequiresGuest。

此时subject.getPrincipal() 结果为null.

@RequiresRoles

例如:@RequiresRoles("aRoleName");

  void someMethod();

如果subject中有aRoleName角色才可以访问方法someMethod。如果没有这个权限则会抛出异常AuthorizationException。

@RequiresPermissions

例如: @RequiresPermissions({"file:read", "write:aFile.txt"} )
  void someMethod();

要求subject中必须同时含有file:read和write:aFile.txt的权限才能执行方法someMethod()。否则抛出异常AuthorizationException。

Apache Shiro 使用 RequiresPermissions with Spring...

Apache Shiro 使用 RequiresPermissions with Spring...

Via:
http://zhidao.baidu.com/question/397868108.html

http://yingzhuo.iteye.com/blog/1709002

根据官方文档在启用Shiro 注解(例如,@RequiresRoles,@RequiresPermissions 等等)时,
需要Shiro 的Spring AOP 集成来扫描合适的注解类以及执行必要的安全逻辑。
只需添加这两个bean 定义到applicationContext-shiro.xml 中:

<beandepends-on="lifecycleBeanPostProcessor"/>

<bean>
    <property name="securityManager" ref="securityManager"/>
</bean>


但是,在使用Spring MVC 的情况下,会遇到:
Exception: org.hibernate.HibernateException: No Session found for current thread

解决方法:
将以上代码移至Spring MVC 的servlet 配置文件,如:applicationContext-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-3.2.xsd
           http://www.springframework.org/schema/mvc
           http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
    
    <!-- Scans the classpath of this application for @Components to deploy as beans -->
    <!-- 只应加装表现层Bean,否则可能引起问题 -->
    <!-- 此处只应该加载表现层组件,如果此处还加载dao层或service层的bean会将之前容器加载的替换掉,而且此处不会进行AOP织入,所以会造成AOP失效问题(如事务不起作用) -->
    <context:component-scan base-package="com.binaryoptions.controller">
    	<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>
    
    <!-- 其他spring-mvc框架配置 -->
	
    <bean id="viewResolver"
                p:view        p:prefix="/views/"
        p:suffix=".jsp" />
		
    <!-- more bean definitions go here -->
    <!-- 为安全检查使用Shiro 的注解(例如,@RequiresRoles,@RequiresPermissions 等等)。 -->
    <!--   
        以下两个bean的配置是为了在Controller层使用元注释控制权限  
        如果使用spring-mvc一定要不要放在webroot的配置文件中  
     -->
    <beandepends-on="lifecycleBeanPostProcessor"/>

    <bean>
        <property name="securityManager" ref="securityManager"/>
    </bean>
	
    <bean>  
        <property name="exceptionMappings">  
            <props>  
                <prop key="org.apache.shiro.authz.UnauthorizedException">/403</prop>
            </props>  
        </property>
    </bean>

</beans>



关于如何在基于 django 类的视图上使用 permission_required 装饰器django界面设计的问题我们已经讲解完毕,感谢您的阅读,如果还想了解更多关于@login_required之后的Django重定向到下一个、@requirespermissions 无效问题原因、@RequiresPermissions 解释、Apache Shiro 使用 RequiresPermissions with Spring...等相关内容,可以在本站寻找。

本文标签: