views:

1742

answers:

4

Hi Everybody.

So, I come from a ASP.NET 2.0 WebForms background and am new to ASP.NET MVC which I find it wonderful, however, i've been somewhat accostumed to it.

This time, my problem has to do with Authentication and Authorization Model:

I used to restrict folders via Web.config's authorization section

 <authorization>
  <deny users="?"/>
  <!--
  <allow users="*"/>
  -->
 </authorization>

So when a user tries to access a private "page" be redirected to index page; How can I do this on MVC? I used to save the user id (or object) in the session data... now I don't know how or where to store it, in a MVC'ish way.

As a side note, my data model has a table like this:

CREATE TABLE user_perm (
    user INT,
    feature INT,
)

And I would like to restrict access to certain controllers based on the content of this table. Ho w can I achieve it?

PS: i'm aware of these other questions, but they refer to beta version and I'm unsure if yet apply to the current released version.

Thanks in advance

+2  A: 

Have a look at this blog post: Securing your controller actions

Praveen Angyan
+2  A: 

You should try attribute filtering on controller actions. (See this link for good information.)

Controller actions point you to actual 'pages', you should secure those.

What I use (custom attribute...):

Public Class ProjectController
    Inherits System.Web.Mvc.Controller

    <Models.Authentication.RequiresAuthentication()> _
    Function Edit(ByVal id As Integer) As ActionResult

    End Function

    <Models.Authentication.RequiresRole(Role:="Admin")> _
    Function Delete(ByVal id As Integer) As ActionResult

    End Function
End Class

And the authorization attribute:

Namespace Models.Authentication
    Public Class RequiresAuthenticationAttribute : Inherits ActionFilterAttribute
        Public Overrides Sub OnActionExecuting(ByVal filterContext As System.Web.Mvc.ActionExecutingContext)
            If Not filterContext.HttpContext.User.Identity.IsAuthenticated Then
                Dim redirectOnSuccess As String = filterContext.HttpContext.Request.Url.AbsolutePath
                Dim redirectUrl As String = String.Format("?ReturnUrl={0}", redirectOnSuccess)
                Dim loginUrl As String = FormsAuthentication.LoginUrl + redirectUrl

                filterContext.HttpContext.Response.Redirect(loginUrl, True)
            End If
        End Sub
    End Class

    Public Class RequiresRoleAttribute : Inherits ActionFilterAttribute
        Private _role As String

        Public Property Role() As String
            Get
                Return Me._role
            End Get
            Set(ByVal value As String)
                Me._role = value
            End Set
        End Property

        Public Overrides Sub OnActionExecuting(ByVal filterContext As System.Web.Mvc.ActionExecutingContext)
            If Not String.IsNullOrEmpty(Me.Role) Then
                If Not filterContext.HttpContext.User.Identity.IsAuthenticated Then
                    Dim redirectOnSuccess As String = filterContext.HttpContext.Request.Url.AbsolutePath
                    Dim redirectUrl As String = String.Format("?ReturnUrl={0}", redirectOnSuccess)
                    Dim loginUrl As String = FormsAuthentication.LoginUrl + redirectUrl

                    filterContext.HttpContext.Response.Redirect(loginUrl, True)
                Else
                    Dim hasAccess As Boolean = filterContext.HttpContext.User.IsInRole(Me.Role)
                    If Not hasAccess Then
                        Throw New UnauthorizedAccessException("You don't have access to this page. Only " & Me.Role & " can view this page.")
                    End If
                End If
            Else
                Throw New InvalidOperationException("No Role Specified")
            End If

        End Sub
    End Class
End Namespace
Ropstah
ewww VerBose.net :P
Nathan Ridley
Sorry, i go way back on VB :). I really like C# / Javascript constructs and really HATE the line continuation mark _ for VB. But VB is perfectly readable to me. Hurray for intellisense hehe
Ropstah
+1  A: 

use the Authorize attribute. You can place it on individual actions or on the entire controller.

[Authorize(Roles="admin")]

More information here:

http://forums.asp.net/p/1428467/3192831.aspx

Nathan Ridley
And how to do it based on the user_perm table? should I inherit Authorize?
Jhonny D. Cano -Leftware-
You should build a custom attribute. Please see my answer with the custom attribute example....
Ropstah
Yeah I use my own custom attribute for my stuff - check out ropstah's example.
Nathan Ridley
A: 

They way we are handling it is through Attributes.

    [Authorize]
    public ActionResult SomeAction() {
        return View();
    }

“[Authorize]” is equvalent to “[Authorize(Roles="user")]”. For specific roles use [Authorize(Roles="")].

Jack Marchetti