Asp.net mvc 确定AuthorizeAttribute是在类级别还是在方法级别
我正在创建一个自定义AuthorizeAttribute,我想在自定义AuthorizeAttribute的New()方法中检查当前属性是在类(控制器)级别还是在方法(操作)级别声明的 我的控制器:Asp.net mvc 确定AuthorizeAttribute是在类级别还是在方法级别,asp.net-mvc,vb.net,Asp.net Mvc,Vb.net,我正在创建一个自定义AuthorizeAttribute,我想在自定义AuthorizeAttribute的New()方法中检查当前属性是在类(控制器)级别还是在方法(操作)级别声明的 我的控制器: <CustomAuthorization> Public Class SeomController ... <CustomAuthorization> Function Index() As ActionResult 这不是你问题的答案,但可能是另一种选择
<CustomAuthorization>
Public Class SeomController
...
<CustomAuthorization>
Function Index() As ActionResult
这不是你问题的答案,但可能是另一种选择 向自定义属性类添加属性
Public Enum Levels
Controller
Action
End Enum
Public Class CustomAttributes
Public Class CustomAuthorize
Inherits System.Web.Mvc.AuthorizeAttribute
Private _level As Levels
Public Property Level() As Levels
Get
Return _level
End Get
Set(ByVal value As Levels)
_level = value
End Set
End Property
Protected Overrides Function AuthorizeCore(httpContext As HttpContextBase) As Boolean
If (_level = Levels.Controller) Then
'Controller Level
End If
Return MyBase.AuthorizeCore(httpContext)
End Function
End Class
End Class
然后,您可以在添加属性时仅指示该属性的指定位置
<CustomAttributes.CustomAuthorize(Level:=Levels.Controller)>
Public Class AccountController
<CustomAttributes.CustomAuthorize(Level:=Levels.Action)>
Public Function Login(returnUrl As String) As ActionResult
ViewBag.ReturnUrl = returnUrl
Return View()
End Function
公共类帐户控制器
作为ActionResult的公共函数登录(返回URL作为字符串)
ViewBag.ReturnUrl=ReturnUrl
返回视图()
端函数
属性,因此不建议创建自我感知属性
但是如果您采用链接文章中的方法,您可以创建一个全局IAuthorizationFilter
,以确定属性的注册位置
CustomAuthorizationAttribute
首先,您需要一个“dumb”authorize属性,它只是一个属性(而不是AuthorizeAttribute
子类),用于标记控制器和操作。它足够聪明,可以收集元数据并将其拆分为数组以便于访问,但仅此而已
<AttributeUsage(AttributeTargets.[Class] Or AttributeTargets.Method, Inherited := True)> _
Public Class CustomAuthorizationAttribute
Inherits Attribute
Private m_users As String
Private m_usersSplit As String()
Private m_roles As String
Private m_rolesSplit As String()
Public Property Users() As String
Get
Return Me.m_users
End Get
Set
Me.m_users = value
Me.m_usersSplit = SplitString(value)
End Set
End Property
Public Property Roles() As String
Get
Return Me.m_roles
End Get
Set
Me.m_roles = value
Me.m_rolesSplit = SplitString(value)
End Set
End Property
Friend ReadOnly Property UsersSplit() As String()
Get
Return Me.m_usersSplit
End Get
End Property
Friend ReadOnly Property RolesSplit() As String()
Get
Return Me.m_rolesSplit
End Get
End Property
Friend Shared Function SplitString(original As String) As String()
If String.IsNullOrEmpty(original) Then
Return New String(-1) {}
End If
Return (From piece In original.Split(New Char() {","C})Let trimmed = piece.Trim() Where Not String.IsNullOrEmpty(trimmed)trimmed).ToArray(Of String)()
End Function
End Class
用法
全局注册您的CustomAuthorizationFilter
,以便它可以检测您的属性所在位置(并运行任何其他授权逻辑)
然后正常装饰你的控制器和动作
<CustomAuthorization>
Public Class SeomController
...
<CustomAuthorization>
Function Index() As ActionResult
公共类SeomController
...
函数Index()作为ActionResult
您可以添加一个参数并使用它<代码>自定义授权(Level=Levels.Class)]是的,如果我没有找到不需要在控制器/操作级别上添加任何额外内容的解决方案,我正计划这样做哇!对谢谢你,谢谢你花时间用VB写下这一切!欢迎光临。虽然我不是用VB写的,而是用C#写的,然后用了一个转换器:)。我认为它转换正确,但是如果它的任何部分没有编译,请告诉我。是的,我认为CustomAuthorizationFilter中的CustomAuthorization
显示的是CustomAuthorizationAttribute,修剪的部分没有编译,尽管我看到了您在那里尝试的操作。。。
Public Class CustomAuthorizationFilter
Inherits AuthorizeAttribute
Private Enum Level
Action
Controller
End Enum
Private Function GetCustomAuthorizationAttribute(actionDescriptor As ActionDescriptor, ByRef registeredLevel As Level) As CustomAuthorizationAttribute
Dim result As CustomAuthorizationAttribute = Nothing
' Check if the attribute exists on the action method
result = DirectCast(actionDescriptor.GetCustomAttributes(attributeType := GetType(CustomAuthorizationAttribute), inherit := True).SingleOrDefault(), CustomAuthorizationAttribute)
If result IsNot Nothing Then
registeredLevel = Level.Action
Return result
End If
' Check if the attribute exists on the controller
result = DirectCast(actionDescriptor.ControllerDescriptor.GetCustomAttributes(attributeType := GetType(CustomAuthorizationAttribute), inherit := True).SingleOrDefault(), CustomAuthorizationAttribute)
registeredLevel = Level.Controller
Return result
End Function
Protected Overrides Function AuthorizeCore(httpContext As HttpContextBase) As Boolean
Dim actionDescriptor = TryCast(httpContext.Items("ActionDescriptor"), ActionDescriptor)
If actionDescriptor IsNot Nothing Then
Dim registeredLevel As Level
Dim authorizeAttribute = Me.GetCustomAuthorizationAttribute(actionDescriptor, registeredLevel)
' If the authorization attribute exists
If authorizeAttribute IsNot Nothing Then
If registeredLevel = Level.Action Then
' Attribute is registered on an action
' Implement user and role checking logic using
'
' authorizeAttribute.RolesSplit
' authorizeAttribute.UsersSplit
ElseIf registeredLevel = Level.Controller Then
' Attribute is registered on a controller
' Implement user and role checking logic using
'
' authorizeAttribute.RolesSplit
' authorizeAttribute.UsersSplit
End If
End If
End If
Return True
End Function
Public Overrides Sub OnAuthorization(filterContext As AuthorizationContext)
' Pass the current action descriptor to the AuthorizeCore
' method on the same thread by using HttpContext.Items
filterContext.HttpContext.Items("ActionDescriptor") = filterContext.ActionDescriptor
MyBase.OnAuthorization(filterContext)
End Sub
End Class
Public Class FilterConfig
Public Shared Sub RegisterGlobalFilters(ByVal filters As GlobalFilterCollection)
filters.Add(New CustomAuthorizationFilter())
filters.Add(New HandleErrorAttribute())
End Sub
End Class
<CustomAuthorization>
Public Class SeomController
...
<CustomAuthorization>
Function Index() As ActionResult