ASP.NET MVC 5 Wrong Redirect Login Page

2019-05-22 20:29发布

问题:

I'm creating ASP.NET MVC 5 with "Individual User Accounts" Authentication Template. Then I create custom login page to authenticate user from database with Forms Authentication.

<authentication mode="Forms">
  <forms loginUrl="~/User/SignIn" timeout="2880" protection="All" />
</authentication>

For testing the custom login page, I add HomeController with Authorize attribute. After run the visual studio, it redirect to the SignIn page

The problem is when I remove Authorize attribute at HomeController and add authorize filter at FilterConfig.cs

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new HandleErrorAttribute());
    filters.Add(new AuthorizeAttribute());
}

I've got HTTP error: "HTTP Error 401.0 - Unauthorized". How to fix this?

回答1:

Because i put the correct answer as a comment at least 8 mins before anyone did I'll add it as an answer.

You basically need to add the [AllowAnonymous] attribute to your SignIn action, because essentially the filter you have created is making every action require authorisation to 'view'.

Taken from AllowAnonymous attribute information

"...in ASP.NET MVC 4, it's baked in. By baked in, I mean that: There's a built-in AllowAnonymousAttribute in the the System.Web.Mvc namespace which whitelists actions for anonymous access."

Taken from Global action filters information

"ASP.NET MVC 3.0 introduces global action filters - an easy way to apply an action filter to every action in an MVC application."

[AllowAnonymous]
public ActionResult SignIn() {
}


回答2:

By doing this you place autherization restrictions on the login and register actions. So basicly you need to be autherized to login or register. Placing the allowAnonymous attributes on these actions might solve the problem.



回答3:

You've added a global attribute. You need to append an attribute [AllowAnonymous] to the ones you want to not have the rule applied;

  [AllowAnonymous]
  public ActionResult Home() {
    // ...
  }


回答4:

Becasue you add AuthorizeAttribute to global filter. When you no authorized and access all action will redirect to "~/User/SignIn", But the action mapping "~/User/SignIn" also need you authorized. You can try this:

public class NoNeedAuthorizeAttribute : Attribute
{ 
}

And inherit AuthorizeAttribute override OnAuthorization method, If a action has NoNeedAuthorize attribute then ignore:

public override void OnAuthorization(AuthorizationContext filterContext)
{
    if (!filterContext.ActionDescriptor.GetCustomAttributes(typeof(NoNeedAuthorizeAttribute), true).Any())
    {
        base.OnAuthorization(filterContext);
    }
}

Add the NoNeedAuthorizeAttribute to your SignIn action:

public class UserController : Controller
{
    [NoNeedAuthorize]
    public ActionResult SignIn() 
    {
        //Sign in code..
    }
}

Finally, add 'GlobalAuthorizeAttribute' to globle filter:

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
     filters.Add(new HandleErrorAttribute());
     filters.Add(new GlobalAuthorizeAttribute());
}