将用户凭据从HttpRequestContext注入服务层

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了将用户凭据从HttpRequestContext注入服务层相关的知识,希望对你有一定的参考价值。

我有一个.NET 4.6 WebApi 2.0 OWIN应用程序,它提供HTTP请求。这些请求经过身份验证,我们将某些声明存储在RequestContext ClaimsIdentity(UserId,Client Code)中

我们还拥有控制器,服务和存储库结构。

我们的服务通过Ninject注入控制器,并将存储库注入服务。

当用户执行某些请求时,我们需要检查他们的权限。该服务通常需要知道:UserId,ClientCode,用户有权访问的组以及每个组下的权限(读取,写入等)。最后一个只存储在DataBase中。

执行请求时的当前流程是:从RequestContext声明获取userId和clientCode,使用该userid从DataBase获取Group权限。用这些属性创建一个对象UserCredentials

然后在注入它们之后将此对象传递给Service实例。这是一个示例:

public PeopleController(IPeopleService peopleService, IUserManagementService userManagementService)
    {
        var clientCode = RequestContext.GetClientCode();
        var userId = RequestContext.GetUserId();
        var permissions = userManagementService.GetUserPermissions(userId, clientCode);
        }

        peopleService.InjectCredentials(new services.Models.UserCredentials()
        {
            ClientCode = clientCode,
            UserId = UserId,
            Permissions = UserPermissions

        });
        _peopleService = peopleService;
    }

这对我们来说看起来并不优雅,因为我们需要在任何地方重复该代码并使IPeopleService依赖于用户不会忘记调用InjectCredentials方法。

所以我的问题是,我如何使UserCredentials类可注入,以便它可以作为参数传递给IPeopleService构造函数?

主要的是它依赖于HttpRequestContext,它只能在Controller本身上使用

谢谢

编辑:我知道UserCredentials对象也可以作为参数传递给每个服务方法(实际上比InjectCredentials方法更好)

答案

而不是注入模型,在IUserManagementService实现中注入IHttpContextAccessor。然后实现一个方法来执行您在控制器中的操作。让此方法负责为您提取用户详细信息。

public class UserManagementService : IUserManagementService 
{
   private readonly IHttpContext httpContext;

   public UserManagementService (IHttpContext httpContext)
   {
      this.httpContext = httpContext;
   }



   public UserCredentials GetUserDetails()
   {

new services.Models.UserCredentials()
    {
        ClientCode = clientCode,
        UserId = UserId,
        Permissions = UserPermissions

    });
   }

}

最后,将此服务注入您需要这些详细信息的任何其他服务。

PeopleController(IPeopleService peopleService, IUserManagementService userManagementService)
另一答案

我找到了一种可能的方法,但由于使用了HttpContext.Current.user,我不认为它是推荐的。

kernel.Bind<UserCredentials>().ToMethod(CreateUserCredentials);


private static UserCredentials CreateUserCredentials(IContext arg)
    {
        var identity = HttpContext.Current.User as ClaimsPrincipal;

        int userId = identity.Identity.GetUserId();
        string clientCode = identity.Identity.GetClientCode();
        var userManagementService = kernel.Get<IUserManagementService>();
        if (userId != 0)
        {
            var permisssions = userManagementService.GetUserPermissions(userId, userType, clientCode);
        }
        return new UserCredentials()
        {
            ClientCode = clientCode,
            UserId = userId,
            Permissions = userManagementService.GetUserPermissions(userId, clientCode)
        };

    }

现在,UserCredentials对象可以作为参数添加到构造函数中,并且可以正确初始化。

以上是关于将用户凭据从HttpRequestContext注入服务层的主要内容,如果未能解决你的问题,请参考以下文章

保护好你的后门!通过IPC,凭据和后门对浏览器的攻击研究

是否可以将认证对象(用户凭据)从 struts 传递到 Spring 框架 Web 应用程序?

存储用户凭据 iOS 的推荐方式?

如何将用户凭据传递给 Web 服务?

从工作灯适配器调用受密码保护的 URL 时如何输入用户凭据?

bash 脚本从 bash 脚本添加 git 凭据