Forms Authentication and POST requests from AJAX

前端 未结 2 1183
萌比男神i
萌比男神i 2021-01-18 12:42

We have an ASP.NET app protected by forms authentication. The app uses MS AJAX heavily to call its web-services.

When the forms authentication times out, and a

2条回答
  •  挽巷
    挽巷 (楼主)
    2021-01-18 13:34

    Ok, answering my own questin.

    After looking into this issue and researching a bit more I found that when a web-app is protected by Forms-Authentication and the user is not authenticated, this is what happens:

    • If it's a GET-request - the user is redirected to the login page.
    • If it's a POST-request to a page - the user is redirected to the login page.
    • If it's a POST-request to a web-service - the user gets 401-unauthorized

    Thats how ASP.NET works

    And if a web-service is called by AJAX (xmlHttpRequest object) and returns 401 - of course the browser shows a pop-up login box.

    Now, what should you do is add some code to Application_PostAuthenticateRequest that will prevent throwing 401 for webservices.

    protected void Application_PostAuthenticateRequest(Object sender, EventArgs e)
    {
        if (Request.RequestType == "POST" //if its POST
            && !User.Identity.IsAuthenticated //if user NOT authed
            && !HasAnonymousAccess(Context) //if it's not the login page
            )
        {
            //lets get the auth type
            Configuration config = WebConfigurationManager.OpenWebConfiguration("~");
            SystemWebSectionGroup grp = (SystemWebSectionGroup)config.GetSectionGroup("system.web");
            AuthenticationSection auth = grp.Authentication;
            //if it FORMS auth
            if(auth.Mode== AuthenticationMode.Forms)
            {
    
                //then redirect... this redirect won't work for AJAX cause xmlHttpRequest can't handle redirects, but anyway...
                Response.Redirect(FormsAuthentication.LoginUrl, true);
                Response.End();
    
            }
        }
    }
    public static bool HasAnonymousAccess(HttpContext context)
    {
        return UrlAuthorizationModule.CheckUrlAccessForPrincipal(
            context.Request.Path,
            new GenericPrincipal(new GenericIdentity(string.Empty), null),
            context.Request.HttpMethod);
    }
    

提交回复
热议问题