2015-05-21 6 views
1

У меня ситуация, когда я использую несколько фильтров авторизации для обеспечения различных условий независимо друг от друга:Можно ли переопределить только один фильтр авторизации?

<UserLevelCanAccessThings> 
<UserHasPaidForThings> 
Partial Public Class ThingsController 
    Inherits Controller 

    Function EditThing() As ActionResult 
     ... 
     Return View() 
    End Function 

    <OverrideUserIsPaid> 
    Function PayToUnlockThings() As ActionResult 
     ... 
     Return View() 
    End Function 

End Class 

Теперь у меня есть ситуации, когда мне нужно иметь байпас действие только один из фильтры. Например, предположим, что вам разрешен доступ к этому контроллеру для работы с Things, если вы достигли достаточно высокого уровня (первый фильтр), а затем заплатили за этот доступ (второй фильтр).

Метод оплаты должен обеспечить первое условие, но НЕ второе, потому что я не хочу блокировать пользователя от оплаты, потому что он не оплачен, когда он пытается оплатить!

(я знаю, что я мог двигаться метод Pay где-то еще, но в моей реальной ситуации это нежелательно. Это просто пример, чтобы проиллюстрировать то, что я прошу.)

А глобальные OverrideAuthorization атрибутов очереди выключить ВСЕ авторизацию, но мне нужно быть более избирательным. Как я могу это сделать?

+0

Вы можете проверить это: http://stackoverflow.com/questions/16270190/how-does-one-get-a-list-of-authorization-filters-that-have-been-applied-to-a- но это похоже на то, что вы хотите сделать, вероятно, должно быть спроектировано по-другому. Возможно, претензии или какая-то другая парадигма роли или прав? –

ответ

0

После this answer по Darin, я сделал это:

Public Class OverrideUserIsPaidAttribute 
    Inherits AuthorizeAttribute 

    Public Overrides Sub OnAuthorization(filterContext As AuthorizationContext) 
     'no op 
    End Sub 
End Class 

Public Class UserIsPaidAttribute 
    Inherits AuthorizeAttribute 

    Public Overrides Sub OnAuthorization(filterContext As AuthorizationContext) 
     'get all other filters attached to this action, controller, or globally 
     Dim otherFilters = filterContext.ActionDescriptor.GetCustomAttributes(True).AsEnumerable '.Where(Function(x) TypeOf x Is IAuthorizationFilter And Not TypeOf x Is OverridePlayerIsPaidAttribute).AsEnumerable(Of IAuthorizationFilter)() 
     otherFilters = otherFilters.Union(filterContext.ActionDescriptor.ControllerDescriptor.GetCustomAttributes(True)) 
     otherFilters = otherFilters.Union(GlobalFilters.Filters.Select(Function(x) x.Instance)) 

     'if any of them is an override, bail out before validating 
     If otherFilters.OfType(Of UserIsPaidAttribute).Count > 0 Then Return 

     'regular validation here 
    End Sub 

В основном, это повышает разрешение UserIsPaid для проверки атрибутов действий, контроллер и глобальные фильтры, чтобы увидеть, если есть переопределение указано, и, если это так, просто не делает свое собственное разрешение. Для меня это кажется достаточно чистым, но я открыт для предложений.

Смежные вопросы