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.

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

3 Comments

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.
"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).
"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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.