One solution I've seen is to use .NET's HttpApplicationState class and store tokens in appstate; this way you're not directly messing with Session (which would be a REST antipattern), but you can still track all currently logged in users and use HttpContext/HttpActionContext to x-ref active tokens in the app. The benefit to using HttpActionContext is that it is thread-safe, whereas HttpContext is not, so you can lock the appstate, mess with the HttpContext of an individual request, and then unlock the appstate to allow other threads in.
Since locking/unlocking appstate does tie up the app, I'm not sure how well this solution scales, but here it is anyway . . .
General outline:
When a user first logs in, a token is generated for him/her and stored in appstate. Then you can tag any API calls that require authentication (or that need other information stored on that user) with a custom attribute that checks for that token in the appstate, sending the token name as a header in the API call (e.g. "{token-name: TOKEN}").
Here's a brief example:
[in Controller method first activated at login:]
CustomUserObject user = new CustomUserObject();
//store user props
string token = Guid.NewGuid().ToString();
//create AppState instance, mine's called _appState
//...
_appState.Lock();
_appState[token] = user;
_appState.UnLock();
//...
[Then in 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; //<--- I've created a custom service tier class for appstate stuff
//Get appState instance, however makes sense for you.
//I'm using repo pattern with UnitOfWork, so mine looks like this...
//"IContainer ioc = DependencyResolution.IoC.Initialize();"
//"IAppStateService appService = ioc.GetInstance<IAppStateService>();"
appService.SetHttpApplicationState(HttpContext.Current.Application);
bool isAuthorized = appService.CheckTokenAndDoStuff(token);
//inside that method ^^^ you'll do stuff like
//"_appState.Lock();"
//"if (_appState[token] == null) return false" (or whatever)
//"_appState.Unlock();"
}
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;
}
[then in webapi]
[HttpPost]
[CustomAuthorize]
public HttpResponseMessage NameOfMethod(...)...
...and that should x-check your appstate for your user token for you. Just make sure to include your token in your request header, and make sure to include the Basic Auth info in your response header.