我正在开发一个ASP.NET MVC应用程序。我实现了自定义成员资格提供者,主体和身份。在自定义提供程序中,我在ValidateUser()方法中替换HttpContext.Current.User,如下所示:
public sealed class CustomMembershipProvider : MembershipProvider { ... public override bool ValidateUser(string username, string password) { ... CustomIdentity identity = new CustomIdentity(...); CustomPrincipal cu = new CustomPrincipal(identity); HttpContext.Current.User = cu; ... } ... }
在AccountController中(调用自定义成员资格提供程序),我可以按如下方式访问自定义标识:
public class AccountController : BaseController { ... public ActionResult LogOn(string userName, string password, bool rememberMe, string returnUrl) { ... CustomIdentity ci = (CustomIdentity)HttpContext.User.Identity; ... } ... }
我的所有控制器都继承BaseController,它调用自定义属性,如下所示:
[CustomAttribute] public abstract class BaseController : Controller { ... }
我希望我的其他控制器在AccountController设置之后访问自定义属性中的自定义标识,如下所示:
public class CustomAttribute : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { base.OnActionExecuting(filterContext); CustomIdentity ci = filterContext.HttpContext.User.Identity as CustomIdentity; ... } } }
我发现filterContext.HttpContext.User仍然设置为GenericPrincipal而不是我的CustomPrincipal。因此,我的自定义标识在我的属性过滤器中无法访问。我该怎么做才能在我的属性过滤器中访问我的CustomPrincipal?
提前致谢。
答案 0 :(得分:2)
在研究了更多关于如何触发应用程序请求事件(特定顺序)以及何时可以设置上下文对象之后,我能够设置我的自定义主体和标识,以便它们可用于过滤器(在整个应用程序中) )。
我意识到必须先验证用户,然后才能将这些实体设置为通过应用程序的其余部分使用。我发现,这可以在global.asax的Application_AuthenticateRequest()方法中完成。
所以,我修改了我的逻辑如下:
protected void Application_AuthenticateRequest(object sender, EventArgs e) { if (Request.IsAuthenticated) { // TODO: Add checks so we only do the following once per login. // Get the GenericPrincipal identity IIdentity ui = HttpContext.Current.User.Identity; /* Extract Name, isAuthenticated, AuthenticationType from the identity of the GenericPrincipal and add them including any custom properties to the custom identity. I added a few extra properties to my custom identity. */ CustomIdentity identity = new CustomIdentity(...); /* Although my custom principal does not currently have any additional properties, I created a new principal as I plan to add them in the future. */ CustomPrincipal principal = new CustomPrincipal(identity); // Set custom principal HttpContext.Current.User = principal; } }
这让我超越了我的障碍。如果还有其他更好的方法可以指导我,请指导我。
感谢。
答案 1 :(得分:0)
我不知道这是否“更好”,但到目前为止它对我有用。我创建了一个具有UserContext
属性的静态CurrentUser
类。在那里,我存储了从数据库中获取的用户实体,并将其用于用户信息数据和授权。我只使用HttpContext.Current.User
来检查身份验证。
现在CurrentUser
属性将我的用户对象存储在HttpContext
的{{1}}集合中(我有一个包装器,所以我可以使它可单元测试)。