我更喜欢选项 2(在 Web 层之外使用 Thread.CurrentPrincipal )。因为这不会影响您的服务层和数据层方法。附带奖金:您可以将您的角色 + 附加信息存储在自定义主体中;
确保您的服务和数据层中的 Thread.CurrentPrincipal 与您的 Web 层相同;您可以在 Global.asax(Application_AuthenticateRequest) 中设置您的 HttpContext.Current.User (Context.User)。您可以设置的其他替代位置添加在底部。
示例代码:
//sample synchronizing HttpContext.Current.User with Thread.CurrentPrincipal
protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
HttpCookie authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
//make sure principal is not set for anonymous user/unauthenticated request
if (authCookie != null && Request.IsAuthenticated)
{
FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
//your additional info stored in cookies: multiple roles, privileges, etc
string userData = authTicket.UserData;
CustomPrincipal userPrincipal = PrincipalHelper.CreatePrincipal(authTicket.Name, authTicket.UserData, Request.IsAuthenticated);
Context.User = userPrincipal;
}
}
当然,首先您必须实现您的登录表单以创建包含您的自定义主体的授权 cookie。
Application_AuthenticateRequest 将对服务器的任何请求(css 文件、javascript 文件、图像文件等)执行。要将此功能仅限于控制器操作,您可以尝试在 ActionFilter 中设置自定义主体(我没有尝试过)。我尝试的是在控制器的拦截器中设置此功能(我使用 Castle Windsor 进行依赖注入和面向方面的编程)。