【问题标题】:Check IsInRole without requiring the Authorize attribute?检查 IsInRole 而不需要 Authorize 属性?
【发布时间】:2012-11-28 15:34:44
【问题描述】:

我创建了自己的 Authorize 属性,名为 Authorise...

Imports System.Security.Principal

<AttributeUsage(AttributeTargets.Method Or AttributeTargets.[Class], Inherited:=True, AllowMultiple:=True)>
Public Class AuthoriseAttribute
    Inherits AuthorizeAttribute

    Public Overrides Sub OnAuthorization(filterContext As AuthorizationContext)

        Dim CookieName As String = FormsAuthentication.FormsCookieName

        If Not filterContext.HttpContext.User.Identity.IsAuthenticated OrElse filterContext.HttpContext.Request.Cookies Is Nothing OrElse filterContext.HttpContext.Request.Cookies(CookieName) Is Nothing Then
            HandleUnauthorizedRequest(filterContext)
            Return
        End If

        Dim AuthCookie = filterContext.HttpContext.Request.Cookies(CookieName)
        Dim AuthTicket = FormsAuthentication.Decrypt(AuthCookie.Value)
        Dim Roles As String() = AuthTicket.UserData.Split(","c)

        Dim UserIdentity = New GenericIdentity(AuthTicket.Name)
        Dim UserPrincipal = New GenericPrincipal(UserIdentity, Roles)

        filterContext.HttpContext.User = UserPrincipal
        MyBase.OnAuthorization(filterContext)

   End Sub

End Class

我已经这样做了,所以我可以在属性上使用角色参数,就像这样......

<Authorise(Roles:="Admin")>

这在我需要授权的页面上完美运行。但是,在不需要授权(因此没有 Authorize 属性)的主页上,我想根据用户是否(a)登录和(b)他们是管理员还是管理员来显示不同的项目不是。比如……

@If HttpContext.Current.User.Identity.IsAuthenticated Then
    ' Display a welcome message (this works)
    @If HttpContext.Current.User.IsInRole("Admin") Then
        ' Display a settings link (this does not work)
    End If
End If

“欢迎信息”部分会触发,但“设置链接”部分不会触发。这是有道理的,因为这个视图没有 Authorize 属性。

如何检查没有 Authorize 属性的页面上的 IsInRole?

【问题讨论】:

  • 你有解决办法吗?
  • 抱歉耽搁了。我没有解决这个问题。作为临时解决方法,我正在处理 Application_AuthenticateRequest 中的身份验证。我仍然希望有一个解决方案允许我使用动作过滤器,尽管正如人们提到的那样,它是其他帖子的更好方法。
  • 谢谢你。我尝试了“Application_OnPostAuthenticateRequest”,但是当我调试代码时,它被调用了太多次。这有点矫枉过正。我只需要在几个部分视图中使用 IsInRole。所以我设法创建了一个“ManualOnAuthorization”方法,它只在需要时被调用。

标签: asp.net-mvc-3 isinrole


【解决方案1】:

我对此没有适当的解决方案。在有人发布正确的解决方案之前,只是一个解决方法可能会有所帮助。

我对动作使用 [Authorize] 属性,但每当我处于局部视图中时,我都会手动执行“OnAuthorization”。

public class Authorize : AuthorizeAttribute
{
 public override void OnAuthorization(AuthorizationContext filterContext)
 {
   ....
 }

 public static void ManualOnAuthorization(HttpContext context)
 {
    if (context.User.Identity.IsAuthenticated && context.User.Identity.AuthenticationType == "Forms")
    {
        FormsIdentity fIdent = (FormsIdentity)context.User.Identity;
        var user = new CustomUser(fIdent.Ticket.UserData);
        var ci = new CustomIdentity(user);
        var p = new CustomPrincipal(ci);
        HttpContext.Current.User = p;
        Thread.CurrentPrincipal = p;
    }
 }
}

我已经把它放在了 Authorize 类中,并在局部视图中使用它。

@if(User.Identity.IsAuthenticated)
    {
        Authorize.ManualOnAuthorization(HttpContext.Current); 
        if (User.IsInRole("Admin"))
        {
        }
    }

【讨论】:

  • 对我来说,我想在每个页面上显示我的“管理员”链接(如果以管理员身份登录),因此我在布局页面中有它。所以我认为你的临时解决方案会像我的临时解决方案一样经常被调用。不过还是谢谢。
  • 就像一个想法。假设我们一天有 10 万次观看,而只有 2 万次观看是针对已登录用户的。在这种情况下,ManualOnAuthorization 只会被调用 20k 次。因为我们有条件 User.Identity.IsAuthenticated。无论他们是否登录,每个视图都会调用 3 到 4 次“Application_OnPostAuthenticateRequest”。谢谢
  • 其实很好。我猜大多数时候用户不会登录我们的网站,所以目前这是一个很好的解决方法。
猜你喜欢
  • 1970-01-01
  • 2020-04-04
  • 1970-01-01
  • 2017-03-15
  • 1970-01-01
  • 2011-09-30
  • 2015-05-16
  • 1970-01-01
  • 2023-03-29
相关资源
最近更新 更多