我们正在开发一个Web应用程序,用户可以在其中注册订单、客户等,并随后对其进行查看。我们有一些服务用于MVC控制器与Web UI接口。现在我们面临多个用户的问题:每个服务应该提供当前授权用户ID,因此所有操作(CRUD和业务逻辑)只允许该用户ID执行。如何传递它呢?我考虑将参数传递给我的IDataService(服务基类),这是由WhateverController实例化的,后者又可以访问User.Identity.GetUserId()方法,但由于我正在使用IoC容器(Ninject),我不知道怎么做。我猜IDataService需要一个IUserInfoProvider的引用,以便它可以调用IUserInfoProvider.GetUserId()。然后,我可以以某种方式注入一个基于Identity和具有当前Web上下文信息的实现,基本上与必须实例化Controller的方式相同。
问题是:如何获取这些数据?
当然,更简单的解决方案是在每个控制器构造函数中手动执行此操作,但应该有一种更自动化和优雅的方式来解决这个问题。
编辑:经过进一步的研究,感谢Cuong Le的答案,我必须问的问题实际上是“如何从当前上下文注入UserManager?”。
但是,为了将我的服务层与MVC分离,我创建了一个IUserInfoProvider,它提供对已验证的用户数据的访问。基于Identity和UserManager的实现位于Web UI(MVC)项目中,因此它具有像Cuong Le建议的IPrincipal和ApplicationUserManager一样的内容,所有这些都使用Ninject注入。
以下接口抽象了来自Identity和UserManager的用户信息。
这里是在MVC项目中使用Identity和UserManager实现的方法。
问题是:如何获取这些数据?
当然,更简单的解决方案是在每个控制器构造函数中手动执行此操作,但应该有一种更自动化和优雅的方式来解决这个问题。
编辑:经过进一步的研究,感谢Cuong Le的答案,我必须问的问题实际上是“如何从当前上下文注入UserManager?”。
但是,为了将我的服务层与MVC分离,我创建了一个IUserInfoProvider,它提供对已验证的用户数据的访问。基于Identity和UserManager的实现位于Web UI(MVC)项目中,因此它具有像Cuong Le建议的IPrincipal和ApplicationUserManager一样的内容,所有这些都使用Ninject注入。
以下接口抽象了来自Identity和UserManager的用户信息。
public interface IUserInfoProvider<T>
{
string GetUserId();
T GetUserData();
}
这里是在MVC项目中使用Identity和UserManager实现的方法。
public class IdentityUserInfoProvider : IUserInfoProvider<DatosEmpresa>
{
private readonly ApplicationUserManager _userManager;
private readonly IPrincipal _user;
public IdentityUserInfoProvider(ApplicationUserManager userManager, IPrincipal user)
{
_userManager = userManager;
_user = user;
}
public string GetUserId()
{
return _user.Identity.GetUserId();
}
public DatosEmpresa GetUserData()
{
return _userManager.FindById(_user.Identity.GetUserId()).DatosEmpresa;
}
}
还有Ninject配置部分
kernel.Bind<IUserInfoProvider<DatosEmpresa>>().To<IdentityUserInfoProvider>();
kernel.Bind<IPrincipal>()
.ToMethod(ctx => HttpContext.Current.User)
.InRequestScope();
kernel.Bind<ApplicationUserManager>()
.ToMethod(ctx => HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>())
.InRequestScope();
那么我可以在任何服务对象中使用IUserInfoProvider
,从而获取正确的用户信息。