FormsAuthentication 登入機制
一、Form Authentication
架構圖僅供參考,跟程式無關。
FormsAuthentication 技術主要出現在 webform 時代,
因為 FormsAuthentication 技術相依於 IIS authentication,所以記得還要在 Web.config 再加上
如下預設值,特別是 loginUrl 屬性
<configuration> <system.web> <authentication mode="Forms"> <forms loginUrl="~/" protection="All" timeout="30" name=".ASPXAUTH" path="/" requireSSL="false" slidingExpiration="true" defaultUrl="default.aspx" cookieless="UseDeviceProfile" enableCrossAppRedirects="false" /> </authentication> </system.web> </configuration>
否則驗證會過不了。
loginUrl 屬性值為表示當驗證未過時或未驗證時,要導到哪裡路徑的登入頁面。
架構如圖,與相關範例如下
HomeController.cs
using System.Web.Mvc;
using WebApplication1.Filter;
using System;
using System.Web;
using System.Web.Security;
namespace WebApplication1.Controllers
{
public class HomeController : Controller
{
[AuthorizePlus]
public ActionResult Index()
{
return View();
}
public ActionResult Login()
{
return View();
}
[HttpPost]
public ActionResult Login(string myid)
{
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket
(
1,
"myLogin",
DateTime.Now,
DateTime.Now.AddSeconds(10d),
false,
myid,
FormsAuthentication.FormsCookiePath
);
string encTicket = FormsAuthentication.Encrypt(ticket);
var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket)
{
HttpOnly = true
};
Response.Cookies.Add(cookie);
return RedirectToAction("Index");
}
public ActionResult Logout()
{
FormsAuthentication.SignOut();
ViewBag.Name = "Guest";
return RedirectToAction("Index");
}
[AuthorizePlus]
public ActionResult About()
{
return View();
}
}
}
注意,使用 FormsAuthentication 技術的話,HttpCookie 的 CookieName 要為
FormsAuthentication.FormsCookieName,否則 FormsAuthentication 的驗證機制會失效。
AuthorizePlusAttribute.cs
using System.Web.Mvc;
using System.Web.Security;
namespace WebApplication1.Filter
{
public class AuthorizePlusAttribute : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
if (filterContext.HttpContext.User.Identity.IsAuthenticated)
{
FormsIdentity FormsIdentity = filterContext.HttpContext.User.Identity as FormsIdentity;
filterContext.Controller.ViewBag.Name = FormsIdentity.Ticket.UserData;
}
else
{
HandleUnauthorizedRequest(filterContext);
}
}
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
filterContext.Controller.ViewBag.Name = "Guest";
}
}
}
About.cshtml
@{
ViewBag.Title = "About";
}
<h2>@ViewBag.Title</h2>
<h3 style="color:red;">@ViewBag.Name</h3>
<p>Use this area to provide additional information.</p>
Index.cshtml
@{
ViewBag.Title = "Home Page";
}
<p style="color:red;">Hello! @ViewBag.Name</p>
<div class="jumbotron">
<h1>ASP.NET</h1>
<p class="lead">ASP.NET is a free web framework for building great Web sites and Web applications using HTML, CSS and JavaScript.</p>
<p><a href="https://asp.net" class="btn btn-primary btn-lg">Learn more »</a></p>
</div>
<div class="row">
<div class="col-md-4">
<h2>Getting started</h2>
<p>
ASP.NET MVC gives you a powerful, patterns-based way to build dynamic websites that
enables a clean separation of concerns and gives you full control over markup
for enjoyable, agile development.
</p>
<p><a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkId=301865">Learn more »</a></p>
</div>
<div class="col-md-4">
<h2>Get more libraries</h2>
<p>NuGet is a free Visual Studio extension that makes it easy to add, remove, and update libraries and tools in Visual Studio projects.</p>
<p><a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkId=301866">Learn more »</a></p>
</div>
<div class="col-md-4">
<h2>Web Hosting</h2>
<p>You can easily find a web hosting company that offers the right mix of features and price for your applications.</p>
<p><a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkId=301867">Learn more »</a></p>
</div>
</div>
Login.cshtml
@{
}
<br />
<form action="@Url.Action("Login")" method="post" class="form-inline">
<div class="form-group">
<label for="myid" class="control-label">請輸入登入名稱</label>
<input id="myid" name="myid" type="text" class="form-control" />
<input class="btn btn-primary" type="submit" value="登入" />
</div>
</form>
_Layout.cshtml
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>@ViewBag.Title - My ASP.NET Application</title>
@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
@Html.ActionLink("Application name", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
</div>
<div class="navbar-collapse collapse">
@{
if (HttpContext.Current.User.Identity.IsAuthenticated)
{
<ul class="nav navbar-nav">
<li>@Html.ActionLink("Home", "Index", "Home")</li>
<li>@Html.ActionLink("About", "About", "Home")</li>
<li>@Html.ActionLink("登出", "Logout", "Home", null, new { @class = "btn btn-default" })</li>
</ul>
}
else
{
<ul class="nav navbar-nav">
<li>@Html.ActionLink("Home", "Index", "Home")</li>
<li>@Html.ActionLink("About", "About", "Home")</li>
<li>@Html.ActionLink("登入", "Login", "Home", null, new { @class = "btn btn-link" })</li>
</ul>
}
}
</div>
</div>
</div>
<div class="container body-content">
@RenderBody()
<hr />
<footer>
<p>© @DateTime.Now.Year - My ASP.NET Application</p>
</footer>
</div>
@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/bootstrap")
@RenderSection("scripts", required: false)
</body>
</html>
參考資料:
Explained: Forms Authentication in ASP.NET 2.0
FormsAuthenticationTicket Class