Turning off ASP.Net WebForms authentication for one sub-directory

前端 未结 7 2000
臣服心动
臣服心动 2020-12-15 07:21

I have a large enterprise application containing both WebForms and MVC pages. It has existing authentication and authorisation settings that I don\'t want to change.

7条回答
  •  再見小時候
    2020-12-15 07:39

    I've worked around this the messy way - by spoofing the Forms authentication in the global.asax for all the existing pages.

    I still don't quite have this fully working, but it goes something like this:

    protected void Application_BeginRequest(object sender, EventArgs e)
    {
        // lots of existing web.config controls for which webforms folders can be accessed
        // read the config and skip checks for pages that authorise anon users by having
        //  as the top rule.
    
        // check local config
        var localAuthSection = ConfigurationManager.GetSection("system.web/authorization") as AuthorizationSection;
    
        // this assumes that the first rule will be 
        var localRule = localAuthSection.Rules[0];
        if (localRule.Action == AuthorizationRuleAction.Allow &&
            localRule.Users.Contains("?"))
        {
            // then skip the rest
            return;
        }
    
        // get the web.config and check locations
        var conf = WebConfigurationManager.OpenWebConfiguration("~");
        foreach (ConfigurationLocation loc in conf.Locations)
        {
            // find whether we're in a location with overridden config
            if (this.Request.Path.StartsWith(loc.Path, StringComparison.OrdinalIgnoreCase) ||
                this.Request.Path.TrimStart('/').StartsWith(loc.Path, StringComparison.OrdinalIgnoreCase))
            {
                // get the location's config
                var locConf = loc.OpenConfiguration();
                var authSection = locConf.GetSection("system.web/authorization") as AuthorizationSection;
                if (authSection != null)
                {
                    // this assumes that the first rule will be 
                    var rule = authSection.Rules[0];
                    if (rule.Action == AuthorizationRuleAction.Allow &&
                        rule.Users.Contains("?"))
                    {
                        // then skip the rest
                        return;
                    }
                }
            }
        }
    
        var cookie = this.Request.Cookies[FormsAuthentication.FormsCookieName];
        if (cookie == null ||
            string.IsNullOrEmpty(cookie.Value))
        {
            // no or blank cookie
            FormsAuthentication.RedirectToLoginPage();
        }
    
        // decrypt the 
        var ticket = FormsAuthentication.Decrypt(cookie.Value);
        if (ticket == null ||
            ticket.Expired)
        {
            // invalid cookie
            FormsAuthentication.RedirectToLoginPage();
        }
    
        // renew ticket if needed
        var newTicket = ticket;
        if (FormsAuthentication.SlidingExpiration)
        {
            newTicket = FormsAuthentication.RenewTicketIfOld(ticket);
        }
    
        // set the user so that .IsAuthenticated becomes true
        // then the existing checks for user should work
        HttpContext.Current.User = new GenericPrincipal(new FormsIdentity(newTicket), newTicket.UserData.Split(','));
    
    }
    

    I'm not really happy with this as a fix - it seems like a horrible hack and re-invention of the wheel, but it looks like this is the only way for my Forms-authenticated pages and HTTP-authenticated REST service to work in the same application.

提交回复
热议问题