2012-11-28 25 views
1

我創建了一個叫做授權我自己的授權屬性...檢查IsInRole而不要求授權屬性?

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屬性。

如何在沒有授權屬性的頁面上檢查IsInRole?

+0

你有沒有找到解決方案? – eadam

+0

對不起,延誤了。我沒有解決這個問題。作爲臨時解決方法,我正在處理Application_AuthenticateRequest中的身份驗證。我仍然希望有一個解決方案,可以讓我使用Action Filter,儘管人們已經提到它是其他帖子上更好的方式。 –

+0

謝謝你。我嘗試了'Application_OnPostAuthenticateRequest',但是當我調試代碼時,它被調用了太多次。這有點矯枉過正。我只需要幾個部分視圖中的IsInRole。所以我設法創建了一個'ManualOnAuthorization'方法,只有在需要的時候纔會被調用。 – eadam

回答

0

我對此沒有適當的解決方案。只是在解決問題之前找人解決這個問題可能會有所幫助。

我使用[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")) 
     { 
     } 
    } 
+0

對於我而言,我想在每個頁面上顯示我的「管理員」鏈接(如果以管理員身份登錄),因此我在佈局頁面中顯示該鏈接。所以我認爲你的臨時解決方案和我的臨時解決方案一樣多。不過謝謝。 –

+0

就像一個想法。假設我們一天有10萬次觀看,只有20萬次觀看是登錄用戶。在這種情況下,ManualOnAuthorization只會被調用20k次。因爲我們有條件User.Identity.IsAuthenticated。 'Application_OnPostAuthenticateRequest'被每個視圖調用3到4次,無論它們是否被登錄。 thnx – eadam

+0

其實好點。我猜想大部分時間用戶都不會在我們的網站上登錄,所以現在這是一個很好的解決方法。 –