对于想了解如何在基于django类的视图上使用permission_required装饰器的读者,本文将提供新的信息,我们将详细介绍django界面设计,并且为您提供关于@login_required
对于想了解如何在基于 django 类的视图上使用 permission_required 装饰器的读者,本文将提供新的信息,我们将详细介绍django界面设计,并且为您提供关于@login_required之后的Django重定向到下一个、@requirespermissions 无效问题原因、@RequiresPermissions 解释、Apache Shiro 使用 RequiresPermissions with Spring...的有价值信息。
本文目录一览:- 如何在基于 django 类的视图上使用 permission_required 装饰器(django界面设计)
- @login_required之后的Django重定向到下一个
- @requirespermissions 无效问题原因
- @RequiresPermissions 解释
- Apache Shiro 使用 RequiresPermissions with Spring...
如何在基于 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))
有两种方法可以做到这一点:
适用
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)
使用像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重定向到下一个
我觉得这是一个简单的问题,我只想走一小步。
我想执行以下任意操作(作为下一个参数中的术语):
[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
参数从表单传递login
到auth
并auth
重定向到该参数的方法
目前,我正在尝试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 无效问题原因
给角色赋予了权限,放在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 解释
@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...
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...等相关内容,可以在本站寻找。
本文标签: