我目前的服务是使用MVC来渲染表单,WebApi来回移动我的viewModels,使用signalR进行推送通知等。
如果用户正在浏览网站,他们将使用表单身份验证,但我们正在推出一些移动应用程序,我希望能够使用基本身份验证从移动应用程序中使用webapi和signalr,而无需维护两个单独的控制器组。
我有两个IPrincipal,一个SessionPrincipal和一个BasicPrincipal(其中Session Principal继承了BasicPrincipal并且有一些额外的上下文数据)。这个想法是一些控制器需要在网站上(SessionPrincipal),但网络和移动用户(Basic Principal)都可以访问其他所有控制器。有些人根本不需要任何授权,因此不能拒绝请求。
我目前的方法是通过以下步骤来实现这一目的(为简洁起见省略了一些代码)
Global.asax Application_AuthenticateRequest
var cultureCookie = Request.Cookies["Culture"];
// Set culture ...
var authHeader = Request.Headers["Authorization"];
if (authHeader != null && authHeader.StartsWith("Basic"))
{
//Check Username / Password. If okay...
HttpContext.Current.User = new BasicAuthPrincipal(user);
}
else
{
var authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie != null)
{
// Try and resolve Session from encrypted forms auth data. If okay...
HttpContext.Current.User = new SessionAuthPrincipal(Id, User, Agent);
}
}
个人授权过滤器(SessionMVC,SessionApi,BasicApi)基本归结为:
return HttpContext.Current.User as SessionPrincipal != null;
// Or
return HttpContext.Current.User as BasicPrincipal != null;
因此,如果它们在global.asax中成功设置,则继续执行控制器。
现在,我有一个有效的实施方案,为什么我要求帮助呢?
我不确定某些可能会扰乱这种情况的边缘场景。我是否因为这样实施而烦恼?
我读到HttpContext不是线程安全的,但是Application_AuthenticateRequest应该在其他所有内容之前运行,并且不会对该数据进行进一步的更改,所以我认为它应该没问题。