Question

I'm building a web application, and I would like to make certain functions on the front end visible when a user is logged in as an administrator.

I am using the default membership provider, but I have an extension table called userFields which i use for storing user settings.

I have just added a UserType field to this table, and am now considering how will be best to pick this up on the pages.

I don't really want to have to add extra code to each controller method to get this information out of the db, and pass it through.

Is there a better way to do this, either using the built in roles settings in asp.net membership, OR is there a cool way I can expose this information from my db, in the same way user.identity.name works or (User.Identity.Name).ProviderUserKey;

Was it helpful?

Solution

As long as you are using the standard authentication method that places the user object in the context it shouldn't be too hard. In your view, use Html.RenderPartial and the appropriate controller to accomplish what you want like this...

/Home/Index View:

<div id="menu">
<ul>
<li>Page 1</li>
<li>Page 2</li>
<% Html.RenderPartial("/Home/AdminView"); %>
</ul>
</div>

/Home/Admin View:

<li>Admin 1</li>
<li>Admin 2</li>

/Shared/Empty View:

<!--Empty view for non-viewable admin stuff-->

/Home Controller:

public ActionResult AdminView()
{
  //Check if user is admin
  //This should be your own logic... I usually have a few static methods that the 
  //Users or User object has to assist with checking
  if (Models.User.IsAdmin(HttpContext.User.Identity.Name))
  {
    return View();
  }
  else
  {
    return View("Empty");
  }
}

That should work... It's how I do it. If it's wrong, hopefully someone smarter posts a better answer so we can both learn

EDIT:

Just thought of something else... If your user object implements IPrincipal, you could extract it from the context, cast it to your user type and have the information right in the user class...

Kind of like this

class User : IPrincipal
{
  //Implement IPrincipal stuff
  public string Role { get; set; }
}

Then the admin view logic could look like this:

public ActionResult AdminView()
{
  //Check if user is admin
  //This should be your own logic... I usually have a few static methods that the 
  //Users or User object has to assist with checking
  if ( ((Model.User)HttpContext.User).Role =="Admin" )
  {
    return View();
  }
  else
  {
    return View("Empty");
  }
}

OTHER TIPS

Use the asp.net roles - then you can use authorization attributes on your controllers to ensure that the user has the relevant roles set.

See this question.

This solves the problem of only allowing certain actions/controllers to be accessible to certain users.

It doesn't solve the problem of only making certain features 'visible'. To do that you will need to either create different views (or partial views) and your controller(s) chooses which view to render based on roles - or you write role specific logic directly into your view.

Of course if you store flags for users in a separate table you can do all this based on your own data. Write your own authorization attribute (i.e. an authorization filter), and use your own data to drive views - just pass it to the view as part of the view data - just like any other part of the model.

You say you don't want to write code to pass the data through your controller to the view - but this is kind of what controllers are for - it's the reason they exist. You could write a static method - or a service of some type that access the DB directly from the view, bypassing the controller, but then you might as well just go back to webforms.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top