9

如果您处于控制器上下文中,则可以访问当前经过身份验证的用户。拿一篇文章,如Get the current user, within an ApiController action, without passing the userID as a parameter如何在Web API的服务上下文中访问用户?

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

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

+1

从什么能当前认证的用户进入你的服务停止你的当前HttpContext出方的东西IHttpContextAccessor? –

+0

@KirkLarkin使我的方法签名非常可恶。似乎并不干净。并且让我们说你想公开API并允许它没有一个真正的客户使用它,那么它不是很干净。 –

+0

在这种情况下,似乎您的问题可能更多地是关于如何处理可选身份验证,而不是ASP.NET Web API的具体细节。只要你有能力只有时有一个用户,有一个服务,自动检测是否有用户或只是有一个通过可能不会有很大的不同。 –

回答

7

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

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); 
    } 
} 

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

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

如果自主托管有其他方式访问它。

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

Asp.net的核心引入了类似于这使得服务类访问控制器

public interface IHttpContextAccessor { 
    HttpContext HttpContext { get; } 
} 
+0

啊,现在我明白了。非常感谢 - 它也有效;-)!冷却时间结束后,我会在5个小时内奖励赏金! –

相关问题