简体   繁体   中英

Forms Authentication: How to handle unauthorized authenticated user

I am trying to setup a very basic Forms authentication example.

It is correctly redirecting unauthenticated users to the login page and on submit verifying the credentials and if correct calling:

FormsAuthentication.RedirectFromLoginPage(username.Text, false);

If the user is one named in the authorization section they get their page. If not it bounces them back to the login page with no error.

How can I redirect correctly authenticated but unauthorized users to a specific error page or detect the authorization error to display an error message on the login page bounce back?

Here is my web.config

   <authentication mode="Forms">
      <forms name=".ASPXAUTH" loginUrl="/forms/Login" />
    </authentication>
    <authorization>
      <deny users="?" />
      <allow users="username1, username2" />
      <deny users="*" />
    </authorization>

Update:

Based on the answers / comments / research I've got two working solutions.

  1. Put the following in the Page_Load method of your Login form:

     if (Request.IsAuthenticated && !string.IsNullOrEmpty(Request.QueryString["ReturnUrl"])) { // This is an unauthorized, authenticated request... Response.Redirect("FailedAuthorization.aspx"); }

OR

  1. Put the following in your Global.aspx file:

     protected void Application_EndRequest(object sender, EventArgs e) { if (Response.StatusCode == 401) { //Use the built in 403 Forbidden response Response.StatusCode = 403; //OR redirect to custom page //Response.Redirect("FailedAuthorization.aspx"); } } protected void Application_AuthenticateRequest(object sender, EventArgs e) { if (Request.IsAuthenticated) { // Requires ASP.NET >= 4.5 Response.SuppressFormsAuthenticationRedirect = true; } }

Thank you for all the help with this!

Unfortunately, this is one of those things that ASP.NET continually gets wrong. Even though MS and the .NET framework team full well understand the difference between authentication and authorization, they still insist on treating unauthorized as unauthenticated. I don't know why that is.

This is just a quirk of the FormsAuthentication module handler, in that it returns a 401 Unauthorized instead of a 403 Forbidden. (it doesn't help that the HTTP standard confuses Authentication with authorization as well in this manner).

This is not something you can easily override, so your only recourse would be to do something like checking in your Login page to see if they are already logged in, and if they were redirected... it's not foolproof, but it's one way to handle it.

You don't say what version of .NET you're using, but if you are using .net 4.5 then you have another option, which is to use the SuppressFormsAuthenticationRedirect option as in this article:

Forms authentication: disable redirect to the login page

2 checks: if they're authenticated && if there is a return url (which will be there if sent to the log-in page).

if (Request.IsAuthenticated && !string.IsNullOrEmpty(Request.QueryString["ReturnUrl"]))
{
    // This is an unauthorized, authenticated request... 
    Response.Redirect("~/somewhere.aspx");
}

The Unauthorized redirect Status Code is 302 but this overrides with status 200 when it's redirected to the login page. In order to redirect the user to Unauthorize Page rather than to the login page, the Hack is to implement Application_EndRequest in Global and check for Response Status Code 302, which is a temporary redirect from the current called to action.

protected void Application_EndRequest(object sender, EventArgs e)
    {
        if(HttpContext.Current.Response.StatusCode == 302 && User.Identity.IsAuthenticated)
        {
            HttpContext.Current.Response.Clear();
            HttpContext.Current.Response.Redirect("/UnauthorizedPageUrl");
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM