我正在创建自定义AuthorizeAttribute,如果当前属性已在类(控制器)级别或方法(操作)中声明,我想检查自定义AuthorizeAttribute的New()方法内部水平。
我的控制器:
<CustomAuthorization>
Public Class SeomController
...
<CustomAuthorization>
Function Index() As ActionResult
我的CustomAuthorizationAttribute:
Public Sub New()
' Determine if we're at Controller level or Action level
答案 0 :(得分:2)
属性do not (or at least they should not) have any behavior,因此不建议创建自我感知属性。
但是,如果您在链接文章中采用该方法,则可以创建一个全局IAuthorizationFilter
来确定您的属性的注册位置。
首先,你需要一个愚蠢的&#34;授权属性只是一个属性(不是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
要确定属性的位置,可以继承AuthorizeAttribute
(实现IAuthorizationFilter
),然后为其添加一些逻辑以确定属性的注册位置。
通常,您应该覆盖AuthorizeCore
方法并返回true或false以指示用户是否已获得授权,这就是我显示决策逻辑的位置。
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
全局注册您的CustomAuthorizationFilter
,以便它可以检测您的属性所在位置(并运行任何其他授权逻辑)。
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
答案 1 :(得分:1)
这不是你问题的答案,但可能是另一种选择。
将属性添加到自定义属性类
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