我已经使用.NET 4设置和部署了一个简单的会员制表单认证网站。
我在IIS7中创建了一个虚拟目录(现在转换为 "Application"),并在其中设置了 web.config
虚拟目录下的文件如下。
<configuration>
<system.web>
<authorization>
<deny users="?">
</authorization>
</system.web>
<system.webServer>
<directoryBrowse enabled="true" />
</system.webServer>
</configuration>
很好,我浏览到虚拟目录: 我浏览到虚拟目录:.mydomainbooks
我就会被自动转到由 web.config
在我的根目录下,url路径放置如下。
../Account/Login.aspx?ReturnUrl=%2fbooks
这时,我成功登录,但我没有被重定向到任何地方, 当我手动返回到目录时, ../books
,我又被传送回登录页面,我已经登录了?
所以我很困惑,我的问题是什么?我应该成功认证,然后被重定向回目录,或者至少在我登录后能够手动查看它,对吗?
由于我必须自己解决这个问题,我想我也可以为其他人发布它,以防他们的搜索将他们带到这里。
这是所有你需要使用表单认证的东西,允许你的格式化暴露给匿名用户,在现有的.Net (.aspx)网站和MVC Web应用程序之间传递证书,并在登录后重定向到一个给定的网址。
使用你正在寻找的任何件。
确保你的.Net Web应用程序(.aspx)的虚拟目录Virtual Application路径在Views目录之外。同时确保你在IIS中设置了你的虚拟目录应用(Virtual DirectoryApplication)。
我使用Entity Framework和Identity与SQLServer数据库来验证我的用户。
你的Virtual ApplicationDirectory .Net (.aspx) web.config文件需要包含这个。
<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
<!-- other stuff -->
<system.web>
<authentication mode="Forms">
<forms
loginUrl="login.aspx"
name=".AUTHCOOKIE"
protection="All"
path="/"
domain="your_domain.com"
enableCrossAppRedirects="true"
timeout="60">
</forms>
</authentication>
<authorization>
<deny users="?" />
<allow users="*" />
</authorization>
<machineKey
validationKey="your validation key"
decryptionKey="your decryption key"
validation="SHA1"
decryption="AES"
/>
<!-- other stuff -->
</system.web>
<location path="/path/to/your/site.css">
<system.web>
<authorization>
<allow users="?"></allow>
</authorization>
</system.web>
</location>
<!-- other stuff -->
</configuration>
然后,在你的login.aspx页面后面的代码中,你需要这样的东西。
protected void Login1_Authenticate(object sender, AuthenticateEventArgs e)
{
string username = Login1.UserName;
string pwd = Login1.Password;
/* do your authentication here
connect to user store
get user identity
validate your user
etc
*/
if (user != null)
{
FormsAuthentication.SetAuthCookie(username, Login1.RememberMeSet);
System.Web.HttpCookie MyCookie = System.Web.Security.FormsAuthentication.GetAuthCookie(User.Identity.Name.ToString(), false);
MyCookie.Domain = "your_domain.com";
Response.AppendCookie(MyCookie);
Response.Redirect("~/path/to/your/index.aspx");
}
else
{
StatusText.Text = "Invalid username or password.";
LoginStatus.Visible = true;
}
}
现在,在你的MVC应用程序的web.config文件中添加以下内容:
<configuration>
<!-- other stuff -->
<system.web>
<authentication mode="Forms">
<forms
loginUrl="Account/Login"
name=".AUTHCOOKIE"
protection="All"
path="/"
domain="your_domain.com"
enableCrossAppRedirects="true"
timeout="30"/>
</authentication>
<authorization>
<deny users="?"/>
<allow users="*"/>
</authorization>
<machineKey
validationKey="your validation key"
decryptionKey="your decryption key"
validation="SHA1"
decryption="AES"
/>
<!-- other stuff -->
</system.web>
<location path="/path/to/your/site.css">
<system.web>
<authorization>
<allow users="?"></allow>
</authorization>
</system.web>
</location>
<!-- other stuff -->
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<remove name="FormsAuthenticationModule"/>
<add name="FormsAuthenticationModule" type="System.Web.Security.FormsAuthenticationModule"/>
<remove name="UrlAuthorization"/>
<add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule"/>
</modules>
</system.webServer>
<!-- other stuff -->
</configuration>
在你的MVC AccountController的Login方法应该是这样的:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (ModelState.IsValid)
{
/* do your authentication here
connect to user store
get user identity
validate your user
etc
*/
if (user != null)
{
await SignInAsync(user, model.RememberMe);
FormsAuthentication.SetAuthCookie(model.Email, model.RememberMe);
System.Web.HttpCookie MyCookie = System.Web.Security.FormsAuthentication.GetAuthCookie(User.Identity.Name.ToString(), false);
MyCookie.Domain = "your_domain.com";
Response.AppendCookie(MyCookie);
if (Url.IsLocalUrl(returnUrl))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
else
{
ModelState.AddModelError("", "Invalid username or password.");
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
最后,你的MVC AccountController的注销方法是这样的。
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult LogOff()
{
AuthenticationManager.SignOut();
FormsAuthentication.SignOut();
return RedirectToAction("Login", "Account");
}
你需要添加代码来重定向到 "ReturnUrl "URL,在你登录后,从你的登录页面中的查询字符串中注明。