2

My MVC3 app provides three ways for a user to log on

  1. Email + Alias
  2. OpenID Provider
  3. Username + Password

The first two are for visitors without accounts, allowing them to comment/vote on things; the last is for authors and admin who have db user accounts with elevated privileges. Thus there are two log on forms - one for visitors and one for full users.

Unauthenticated/unauthorized attempts to access a resource are redirected to the login page as standard.

Question:

  1. How might I conditionally redirect these requests to the appropriate? Resources requiring Author/Admin privileges to the full user log on form, and Resources only requiring visitor privileges to the visitors log on form?

  2. Also, might I handle avoiding redirects in the case of an AJAX or partial view call? For instance, I'd like to embed the comments partial view in my entry view, and if they are unauthenticated, not redirect, but simply embed the visitors log on there.

Update: I do not want to maintain 2 Atuhorize attributes.

tereško
  • 58,060
  • 25
  • 98
  • 150
one.beat.consumer
  • 9,414
  • 11
  • 55
  • 98

1 Answers1

1

1- You could inherint from the [AuthorizeAttribute] and customize the implementation to route to the desired Unauthorized page.

See the selected awnser is this question: Redirecting unauthorized controller in ASP.NET MVC

2- If your are loading partials from an ajax call, (ie., $.Get(url) or $("#somediv").Load(url)), make sure the actions called by url are properly decorated with your custom [AuthorizeAttribute].

Otherwise, you will need some logic in your razor views to check if the user is authenticated. Something along the lines of

  @if (User.Identity.IsAuthenticated)
  {
      // Normal case
  }
  else
  {
      @Html.Partial("Login")
  }

Where your Login partial would show the desired login view.

Update

You could implement 2 different attributes, one for each scenario.

[AttributeUsage( AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false )]
public class IsUserAdminAttribute : CustomAuthorizedBaseAttribute
{
    // Custom logic to redirect to admin logon partial/view
    ...
}

[AttributeUsage( AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false )]
public class IsAuthenticatedAttribute : CustomAuthorizedBaseAttribute
{
    // Custom logic to redirect to basic/comment logon partial/view
    ...
}

[AttributeUsage( AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false )]
public abstract class CustomAuthorizedBaseAttribute : AuthorizeAttirbute
{
    // Shared custom logic implementation
    ...
}

And you could use one or the other, depending on the scenario, to decorate your controller actions.

Community
  • 1
  • 1
Matthew Perron
  • 6,201
  • 2
  • 21
  • 24
  • Thanks for the reply. It's close but not what I'm looking for. I've got a custom Authorization Filter/Attribute and was thinking about the `OnAuthorization()` method but I am trying to keep things DRY as possible, so I am trying to avoid having my attribute be aware of Views. As for the AJAX logic, even if I wrapped in in Razor as you suggested, if my attribute causes the redirect, it would cause the same issue, no? Lastly, it seems like I would have to be aware of the required roles to know what log on form they need to be sent to. – one.beat.consumer Dec 19 '11 at 23:59
  • "As for the AJAX logic, even if I wrapped in in Razor as you suggested, if my attribute causes the redirect, it would cause the same issue, no?" Yup, it's either the `[AuthorizeAttribute]` decoration (if you actually call a controller action to render your partial) OR some `@if(User.Identity.IsAuthenticated) {...}` wrapping (if you render a partial without calling any controller action). – Matthew Perron Dec 20 '11 at 21:04
  • "I've got a custom Authorization Filter/Attribute and was thinking about the OnAuthorization() method but I am trying to keep things DRY as possible, so I am trying to avoid having my attribute be aware of Views." Can't you use 2 different classes that inherit from `[AuthorizeAttribute]`? Or, even better, add an inheritance layer in-between your 2 custom `[AuthorizeAttribute]` to hold the common stuff. – Matthew Perron Dec 20 '11 at 21:13