asp.net-mvc-3isinrole

Check IsInRole without requiring the Authorize attribute?


I have created my own Authorize attribute called 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

I've done this so I can use the roles parameter on the attribute, like this...

<Authorise(Roles:="Admin")>

This works perfectly on my pages that require authorisation. However, on my main page, which does not require authorisation (and therefore does not have the Authorise attribute) I would like to display different items depending on whether the user is (a) logged in and (b) whether they are an admin or not. For example...

@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

The "welcome message" part fires but the "settings link" part does not. This makes sense because this view does not have the Authorise attribute.

How can I check the IsInRole on pages that don't have the Authorise attribute?


Solution

  • I don't have a proper solution for this. Just a work around that may help before someone posts the proper solution.

    I use, [Authorize] attribute for the actions but whenever I am in a partial view, I do a manual '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;
        }
     }
    }
    

    I have put it in Authorize class and use it as following in a partial view.

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