您可以將認證令牌存儲在窗體身份驗證cookie的用戶數據的一部分。這樣它就可以在每個請求中使用。
因此,例如,一旦你驗證用戶的憑據可以查詢Web服務,以獲得令牌和手動創建並放出窗體身份驗證Cookie:
[HttpPost]
public ActionResult LogOn(string username, string password)
{
// TODO: verify username/password, obtain token, ...
// and if everything is OK generate the authentication cookie like this:
var authTicket = new FormsAuthenticationTicket(
2,
username,
DateTime.Now,
DateTime.Now.AddMinutes(FormsAuthentication.Timeout.TotalMinutes),
false,
"some token that will be used to access the web service and that you have fetched"
);
var authCookie = new HttpCookie(
FormsAuthentication.FormsCookieName,
FormsAuthentication.Encrypt(authTicket)
)
{
HttpOnly = true
};
Response.AppendCookie(authCookie);
// ... redirect
}
然後,你可以寫一個自定義授權屬性這將讀取該信息並設置自定義通用的身份:
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
public class MyAuthorizeAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
var isAuthenticated = base.AuthorizeCore(httpContext);
if (isAuthenticated)
{
string cookieName = FormsAuthentication.FormsCookieName;
if (!httpContext.User.Identity.IsAuthenticated ||
httpContext.Request.Cookies == null ||
httpContext.Request.Cookies[cookieName] == null)
{
return false;
}
var authCookie = httpContext.Request.Cookies[cookieName];
var authTicket = FormsAuthentication.Decrypt(authCookie.Value);
// This is where you can read the userData part of the authentication
// cookie and fetch the token
string webServiceToken = authTicket.UserData;
IPrincipal userPrincipal = ... create some custom implementation
and store the web service token as property
// Inject the custom principal in the HttpContext
httpContext.User = userPrincipal;
}
return isAuthenticated;
}
}
最後裝點你的控制器/需要與這個屬性認證操作:
[MyAuthorize]
public ActionResult Foo()
{
// HttpContext.User will represent the custom principal you created
// and it will contain the web service token that you could use to
// query the remote service
...
}
謝謝,這太棒了。我會去那裏。 – 2011-04-12 09:46:44
加上w/s令牌在表單票據中得到加密,所以不能被盜或讀(理論上) – 2011-04-12 15:31:15
好極了,但是我把「base.AuthorizeCore(httpContext);」到方法的末尾,就我們想要在角色檢查之前設置主體而言。 – mikalai 2012-07-26 09:20:12