使用 Cachecow 时在 Web API 处理程序中获取用户 ID



我有一个MVC Web Api项目,正在使用MessageHandler记录所有请求和响应。 当 api 请求传入时,标头中的持有者令牌允许 Asp.Net 执行其操作并对该用户进行身份验证。 因此,消息处理程序知道用户是谁,我们将其写入日志文件。

现在,为了加快速度,我正在使用Cachecow进行缓存。 因此,我在 MessageHandler 之后添加了 cachecow 处理程序,当第二个请求进来时,从缓存的角度来看,一切正常。 永远不会命中控制器代码,并且响应从缓存返回。

但是,消息处理程序没有 User.Identity 的值,因此我无法判断谁发出了请求。

我需要记录所有请求并确定谁发出了这些请求,即使控制器中的代码没有命中。

我认为一种解决方法是强制 api 请求在标头中传递持有者令牌和用户 ID。 这样我就可以检查用户 id 声明并使用它来记录谁发出了请求。

protected override async Task OutgoingMessageAsync(string correlationId, string requestInfo, byte[] message, string responseTimeMilliseconds)
        {
            await Task.Run(() =>
                Debug.WriteLine(string.Format("{0} - Response: {1}rn{2}", correlationId, requestInfo, Encoding.UTF8.GetString(message))));
                    );
        }

从缓存获取响应时,用户标识为 null。

?HttpContext.Current.User.Identity
{System.Security.Claims.ClaimsIdentity}
    [System.Security.Claims.ClaimsIdentity]: {System.Security.Claims.ClaimsIdentity}
    AuthenticationType: null
    IsAuthenticated: false
    Name: null

有什么想法吗?

在身份验证过程中,设置对象:

System.Threading.Thread.CurrentPrincipal = YourUserInformationObject;

此对象需要实现"System.Security.Principal.IPrincipal"示例

    public class YourUserInformation : IPrincipal
    {
       public Int32 Id { get; set; }
       public String NameUser { get; set; }
       public IIdentity Identity { get; private set; }

        public YourUserInformation()
        {
            this.Identity = new GenericIdentity(NameUser ?? "");
        }
        public bool IsInRole(string role) { return false; }
    }

在身份验证过程中,您将对象保存在 System.Threading.Thread.CurrentPrincipal 中

    public void Authentication(AuthorizationContext filterContext)
    {
       YourUserInformation user = YourMethodGetUserLogin();                
       System.Threading.Thread.CurrentPrincipal = user ;
    }

好吧,你应该从请求创建HttpContext,在那里你将能够使用User.Identity对象:

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        var context = ((HttpContextBase)request.Properties["MS_HttpContext"]);
        var uname = username = context.User.Identity.Name;
        var response = await base.SendAsync(request, cancellationToken);
        return response;
    }

另请查看这篇文章: http://arcware.net/logging-web-api-requests/

箍这个帮助!

尝试进入

System.Threading.Thread.CurrentPrincipal

最新更新