我看到的一个解决方案是使用.NET的
HttpApplicationState类并在appstate中存储令牌;这样你就不会直接干扰Session(这将是一种REST反模式),但你仍然可以跟踪所有当前登录的用户,并使用HttpContext/HttpActionContext在应用程序中交叉引用活动令牌。使用HttpActionContext的好处是它是线程安全的,而HttpContext不是,因此您可以锁定appstate,干扰单个请求的HttpContext,然后解锁appstate以允许其他线程进入。
由于锁定/解锁appstate会占用应用程序,我不确定这个解决方案的可扩展性如何,但无论如何,这里是大体概述:
当用户首次登录时,为他/她生成一个令牌并存储在appstate中。然后,您可以使用自定义属性标记需要身份验证(或需要存储在该用户上的其他信息)的任何API调用,该属性检查appstate中的令牌,在API调用中发送令牌名称作为标头(例如“{token-name:TOKEN}”)。
以下是一个简短的例子:
[在登录时首先激活的控制器方法中:]
CustomUserObject user = new CustomUserObject();
string token = Guid.NewGuid().ToString();
_appState.Lock();
_appState[token] = user;
_appState.UnLock();
【英译中】在 global.asax 文件中:
public class CustomAuthorize : System.Web.Http.AuthorizeAttribute
{
HttpRequestMessage request = actionContext.ControllerContext.Request;
string token = string.Empty;
if (request.Headers.GetValues("token-name") != null)
{
token = request.Headers.GetValues("token-name").FirstOrDefault().ToString();
IAppStateService appService;
appService.SetHttpApplicationState(HttpContext.Current.Application);
bool isAuthorized = appService.CheckTokenAndDoStuff(token);
}
if (isAuthorized)
{
HttpResponseMessage resp = request.CreateResponse(HttpStatusCode.OK);
resp.Headers.Add("AuthenticationToken", token);
resp.Headers.Add("WWW-Authenticate", "Basic");
resp.Headers.Add("AuthenticationStatus", "Authorized");
}
return isAuthorized;
}
[然后在Web API中]
[HttpPost]
[CustomAuthorize]
public HttpResponseMessage NameOfMethod(...)...
...这样就可以为您的用户令牌检查应用程序状态了。只需确保在请求头中包括您的令牌,并确保在响应头中包括基本身份验证信息。