1

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?

cw_dev
  • 465
  • 1
  • 12
  • 27
  • did u get a solution for this? – eadam Dec 25 '12 at 04:47
  • Sorry for the delay. I did not get a solution to this no. As a temporary workaround I am dealing with Authentication in Application_AuthenticateRequest. I am still hoping for a solution that allows me to use the Action Filter though as people have mentioned it is the better way on other posts. – cw_dev Jan 02 '13 at 09:08
  • Thank you for that. I tried 'Application_OnPostAuthenticateRequest' but when I debug the code, it gets called too many times. Which is kind of an overkill. I just needed IsInRole in few partial views. So I have managed to create a 'ManualOnAuthorization' method which only gets called whenever needed. – eadam Jan 02 '13 at 16:00

1 Answers1

0

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"))
        {
        }
    }
eadam
  • 23,151
  • 18
  • 48
  • 71
  • For me, I want to display my "Admin" link on every page (if logged in as an Admin) and therefore I have it in my Layout page. So I think your temporary solution would be called just as often as my temporary solution. Thanks though. – cw_dev Jan 02 '13 at 16:15
  • Just as a thought. Let's say we have 100k views in a day and only 20k views are for logged in users. In that case ManualOnAuthorization will be called only 20k times. Cause we have condition User.Identity.IsAuthenticated. Where as 'Application_OnPostAuthenticateRequest' gets called 3 to 4 times for each view, no matter they are logged in or not. thnx – eadam Jan 02 '13 at 16:32
  • Good point actually. I'd guess most of the time users will not be logged in on our website so this is a good workaround for now. – cw_dev Jan 03 '13 at 09:20