How to override/change FormsAuthentication LoginUr

2019-01-15 12:59发布

问题:

Is there a way to dynamically change the LoginUrl of FormsAuthentication? What I have is the whole site protected by FormsAuth, but for some pages in a sub folder, I'd like to take the user to different login page, and have FormsAuth handle the ReturnUrl stuff. Is that possible or do I have to write my own redirect code for the sub folder cases?

Here's an example layout:

   ~/LogOn1.aspx
   ~/Protected1.aspx
   ~/Protected2.aspx
   ~/Subfolder/
   ~/Subfolder/LogOn2.aspx
   ~/Subfolder/NotProtected.aspx
   ~/Subfolder/Protected3.aspx

So my web.config looks like:

 <forms loginUrl="~/Splash.aspx" ... />

All of the Protected*.aspx pages have

 <deny users="?">

What I'd like though, is for ~/Subfolder/Protected3.aspx to be redirected to ~/Subfolder/LogOn2.aspx if the user is anonymous.

I did try putting a stripped down version of web.config at ~/Subfolder/web.config:

<?xml version="1.0"?>
<configuration>
   <system.web>
      <authentication mode="Forms">
         <forms loginUrl="~/Subfolder/LogOn.aspx" name="SiteAuth" protection="All" timeout="30" path="/" defaultUrl="~/Subfolder/default.aspx" requireSSL="true" cookieless="UseCookies" enableCrossAppRedirects="false" />
      </authentication>
      <authorization>
         <deny users="?" />
      </authorization>
   </system.web>
</configuration>

But all that gets me is this error:

It is an error to use a section registered as allowDefinition='MachineToApplication' beyond application level. This error can be caused by a virtual directory not being configured as an application in IIS.

I think making the Subfolder dir an application would cause even more problems at this point, but maybe I am wrong. If it was an application, wouldn't that separate all code in ~/Subfolder from the rest of the parent app?

回答1:

The problem you're having is that the Forms element is only allowed at the application level - you can't define it in a sub-web.config.

Unfortunately you also can't define it using a Location element, and the FormsAuthentication.LoginUrl property is read only.

Hunting around a bit, it looks like your best bet would be to have some code on your login page that detects where the user has arrived from (i.e. by checking the value of the "ReturnUrl" query string) and redirecting to your other login page if they are from the subdirectory. However I admit that this doesn't scale well at all if you want custom login pages for multiple sub-directories. :(


In repsonse to your edit - yes, making the sub-folder an application would "solve" this error, but as you point out, you'd then have more problems, as you'd need to move all the relevant binaries, app_code, what have you into that sub-folder as well, so it's not really a solution.



回答2:

I had this problem as well and have just googled here trying to solve it then remembered had done it long ago and what I did was in the default login.aspx page in the root folder in the Page_Load event I did a redirect based on return url to my sub directory manage and its login.aspx page! You'd have to repeat the relevant bit for each sub directory.

public void Page_Load(object sender, EventArgs e)
{
 //check for existence of ReturnUrl in QueryString       
    //if it contains manage redirect to manage login page
    if (!String.IsNullOrEmpty(Request.QueryString["ReturnUrl"]))
    {
        if (Request.QueryString["ReturnUrl"].Contains("manage"))
        {
            Response.Redirect("manage/login.aspx");

        }
    } 
}


回答3:

Each subfolder allows you to have a separate webconfig file. So you could put a web.config in your subfolder with the tags:

<authentication mode="Forms">
    <forms loginUrl="~/Subfolder/LogOn2.aspx" />
</authentication>