您可以将认证令牌存储在窗体身份验证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