将身份用户传递给服务

Art*_*bes 2 c# asp.net-mvc asp.net-identity

我们正在开发一个 Web 应用程序,用户可以在其中注册订单、客户等,然后进行查看。我们有 MVC 控制器使用的服务,以便与 Web UI 交互。

现在我们面临多个用户的问题:每个服务都应该提供当前授权的用户 ID,所以所有操作(CRUD 和业务逻辑)都将只允许该用户 ID。应该怎么通过?

我正在考虑将一个参数传递给我的IDataService(服务的基类),该参数由 实例化WhateverController,后者又可以访问该User.Identity.GetUserId()方法,但是当我使用 IoC 容器(Ninject)时,我不知道如何去做。我想这IDataService需要对 a 的引用IUserInfoProvider,因此它可以调用IUserInfoProvider.GetUserId(). 然后我可以以某种方式注入一个基于 Identity 的实现并拥有当前的 Web 上下文信息,几乎与必须实例化控制器的方式相同。

问题是:如何获取这些数据?

当然,一个更简单的解决方案是在每个 Controller 构造函数中手动完成,但应该有更自动和更优雅的方法来解决这个问题。

编辑:经过更多的研究,感谢 Cuong Le 的回答,我不得不问的问题实际上是“如何从当前上下文注入 UserManager?”。

但是,为了将我的服务层与 MVC 分离,我创建了一个IUserInfoProvider,它提供对经过身份验证的用户数据的访问。基于 Identity 和 UserManager 的实现位于 Web UI (MVC) 项目中,因此它具有IPrincipalCuong Le 的建议,以及ApplicationUserManager,,都使用 Ninject 注入。

以下接口从 Identity 和 UserManager 中抽象出用户信息。

public interface IUserInfoProvider<T>
{
    string GetUserId();
    T GetUserData();
}
Run Code Online (Sandbox Code Playgroud)

下面是使用 Identity 和 UserManager 在 MVC 项目中的实现。

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

和 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();
Run Code Online (Sandbox Code Playgroud)

然后我可以IUserInfoProvider在任何服务对象内部使用它并获得正确的用户。

cuo*_*gle 5

简单的解决方案是您可以放入IPrincipalNInject Container:

kernel.Bind<IPrincipal>().ToMethod(context => HttpContext.Current.User);
Run Code Online (Sandbox Code Playgroud)

因此,您ServiceBase可以IPrincipal通过属性或构造函数注入,如下所示:

class ServiceBase
{
    [Inject]
    public IPrincipal User { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

现在您可以从该属性中获取信息。