Plagued by this problem for many years, today finally found a more simple solution to share.
Problem scenarios
Suppose we set the FormsAuthentication in the web.config of the i.cnblogs.com site as follows:
<authentication mode= "Forms" >
<forms name= ". Cnblogs" Loginurl= "https://passport.cnblogs.com/login.aspx" protection= "All" path= "/"/>
</authentication>
When we visit a URL that needs to be logged in before we can access it, for example: Http://i.cnblogs.com/post/list, the request is redirected to the following address:
Https://passport.cnblogs.com/login.aspx?ReturnUrl=%2fpost%2flist
Look! Passing the ReturnUrl query parameter to the login page is a relative path-that's the problem. Because the access page and the login page is not the same level two domain name, use this relative path is return does not come back.
The root of the problem
Take a look at System.Web.Security.FormsAuthentication's code and immediately know the cause of the problem: Ilspy
Internal static string Getloginpage (string extraquerystring, bool Reusereturnurl)
{
//...
if (Text2 = = null)
{
Text2 = Httputility.urlencode (current. Request.rawurl, current. request.contentencoding);
}
Text = text + Formsauthentication.returnurlvar + "=" + Text2;
if (!string. IsNullOrEmpty (extraquerystring))
{
Text = text + & + extraquerystring;
}
return text;
Visible from the code, Microsoft simply ignores the login page is not the same level two domain name of the basic application scene, and has been ignored to the present.
Previous Solutions
Adds a staging page to the current site, redirected from the staging page to the login page.
As a result, the Web.config settings become the following, first redirect to the current site of the login Transfer page.
<authentication mode= "Forms" >
<forms name= ". Cnblogs" Loginurl= "~/account/login" protection= "All" path= "/"/>
</authentication>
Then, use the absolute path as the ReturnUrl value on the staging page and redirect to the real login page.
The sample code for the staging page is as follows:
public class Accountcontroller:controller
{public
actionresult Login (string returnurl)
{
return Redirect ("Https://passport.cnblogs.com/login.aspx?") Returnurl= "+
Httputility.urlencode (" http://"+ Request.Url.Host) + ReturnUrl);
}
Although solve the problem, but for such a solution, I think some long-winded, always feel that there is a better solution, but has not been found.
Face this problem again today, ruthless a little heart, unexpectedly had an unexpected harvest!
A simpler way to solve
Forms validation, the work in the front-line, the most bitter the most tired is System.Web.Security.FormsAuthenticationModule.
It calls the OnAuthenticate method in OnEnter (object source, EventArgs EventArgs):
System.Web.Security.FormsAuthenticationModule
private void OnEnter (object source, EventArgs EventArgs)
{
//...
This. OnAuthenticate (new Formsauthenticationeventargs (context));
//...
}
The following event handling is available in the OnAuthenticate () method:
private void OnAuthenticate (Formsauthenticationeventargs e)
{
HttpCookie httpcookie = null;
if (This._eventhandler!= null)
{
This._eventhandler (this, e);
}
//...
}