【问题标题】:How to access User in a service context in web API?如何在 Web API 的服务上下文中访问用户?
【发布时间】:2018-02-03 19:47:51
【问题描述】:

如果您在控制器上下文中,则可以访问当前经过身份验证的用户。拍Get the current user, within an ApiController action, without passing the userID as a parameter之类的文章。

但是,如果我的控制器调用了一个服务(相同的程序集),但这里我没有控制器上下文。

真正获得经过身份验证的用户的最佳方法是什么?

【问题讨论】:

  • 是什么阻止您将当前经过身份验证的用户传递给您的服务?
  • @KirkLarkin 让我的方法签名变得非常琐碎。好像没有那么干净。假设您想公开 API 并允许它在没有实际客户使用的情况下使用它,那么它并不是很干净。
  • 在这种情况下,您的问题似乎更多是关于如何处理可选身份验证而不是 ASP.NET Web API 的细节。一旦您担心自己只能偶尔拥有用户,拥有一个自动检测是否有用户或只是有一个用户的服务可能不会有很大的不同。
  • 如果有用的话可以看看这个教程:stormpath.com/blog/10-minute-asp-net-user-authentication

标签: asp.net asp.net-web-api asp.net-web-api2 asp.net-identity


【解决方案1】:

您可以创建一个中间服务来提供该功能

public interface IPrincipalProvider {
    IPrincipal User { get; }
}

public class WebApiPrincipalProvider : IPrincipalProvider {
    public IPrincipal User { 
        get {
            return HttpContext.Current != null
                ? HttpContext.Current.User 
                : null;
        }
    }
}

并将其注入到依赖的服务上下文中

public class MyService : IService {
    private readonly IPrincipalProvider provider;

    public MyService(IPrincipalProvider provider) {
        this.provider = provider;
    }

    public MyModel MyServiceMethod() {
        var currentUser = provider.User;
        var name = currentUser.Identity.Name;

        //...use user....

        return model;
    }
}

最后确保抽象和实现在主应用程序的组合根目录中注册到 DI 容器,这样当服务注入控制器时,它也能够访问当前请求的用户。

[Authorize]
public class MyController : ApiController {
    public readonly IService service;

    public MyController (IService service) {
        this.service = service;
    }

    [HttpGet]
    public IHttpActionResult MyGetActiom() {
        var model = service.MyServiceMethod();
        return Ok(model);
    }
}

当身份框架对用户进行身份验证时,会为当前上下文设置用户主体。

如果托管在 IIS 中,您可以点击 HttpContext 来访问用户,就像前面提供的示例一样。 MVC 和 Web API 基本上做了类似填充 Controller.UserApiController.User 的事情。

如果自托管还有其他方法可以访问它。

事实是,一旦通过身份验证,用户就可以使用。将其封装在抽象之后,您可以在控制器之外的任何需要的地方注入它。

Asp.net Core 引入了类似 IHttpContextAccessor 的东西,它允许服务类访问控制器外部的当前 HttpContext

public interface IHttpContextAccessor {
    HttpContext HttpContext { get; }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-27
    • 1970-01-01
    • 2016-09-27
    • 1970-01-01
    • 2022-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多