我们如何在ASP.NET Web API中记录身份验证令牌请求

thi*_*ag0 9 c# asp.net authentication api delegatinghandler

我们有一个ASP.NET Web Api应用程序,它使用OAuth Bearer Tokens进行身份验证,我们正在尝试实现请求/响应日志记录.

基本上它的工作方式如下:
1.用户向"/ authenticate"发送请求并接收身份验证令牌
2.然后,用户使用此身份验证令牌对暴露的API方法发出请求

对于将请求记录到公开的API方法,我们使用的DelegatingHandler是完全正常的.

但是,DelegatingHandler实现不会捕获对"/ authenticate"的请求.

记录令牌请求是否需要不同的方法?

public abstract class MessageHandler : DelegatingHandler
{
    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        var correlationId = Guid.NewGuid();

        var requestInfo = string.Format("{0} {1}", request.Method, request.RequestUri);

        var requestContent = await request.Content.ReadAsByteArrayAsync();

        var context = ((HttpContextBase)request.Properties["MS_HttpContext"]);

        await IncomingMessageAsync(correlationId, request.Method, request.RequestUri, request.Headers, requestContent, 
            context.Request.UserHostAddress, context.Request.IsAuthenticated, context.User.Identity.Name);

        var response = await base.SendAsync(request, cancellationToken);

        byte[] responseMessage;

        responseMessage = await response.Content.ReadAsByteArrayAsync();

        await OutgoingMessageAsync(correlationId, response.StatusCode, response.Headers, responseMessage);

        return response;
    }

    protected abstract Task IncomingMessageAsync(Guid correlationId, HttpMethod requestMethod, Uri requestUri, HttpRequestHeaders requestHeaders, byte[] messageContent, string ipAddress, bool isAuthenticated, string requestMadeByUserName);
    protected abstract Task OutgoingMessageAsync(Guid correlationId, HttpStatusCode statusCode, HttpResponseHeaders responseHeaders, byte[] messageContent);
}
Run Code Online (Sandbox Code Playgroud)

编辑w/OAuth代码

[assembly: OwinStartup(typeof(MyApp.Infrastructure.IdentityConfig))]
namespace MyApp.Infrastructure
{
    public class IdentityConfig
    {
        public void Configuration(IAppBuilder app)
        {
            app.CreatePerOwinContext<ApplicationIdentityDbContext>(() => ApplicationIdentityDbContext.Create(ConfigurationDataProvider.MYDBCONNSTRING));
            app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
            app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);

            app.UseOAuthBearerTokens(new OAuthAuthorizationServerOptions
            {
                 Provider = new ApplicationAuthProvider(),
                 AllowInsecureHttp = true,
                 TokenEndpointPath = new PathString("/Authenticate")
            });
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Mvd*_*vdD 5

您正在安装OWIN中间件以在WebAPI中间件之前发出令牌。

 app.UseOAuthBearerTokens(new OAuthAuthorizationServerOptions
     {
         Provider = new ApplicationAuthProvider(),
         AllowInsecureHttp = true,
         TokenEndpointPath = new PathString("/Authenticate")
     });
Run Code Online (Sandbox Code Playgroud)

DelegatingHandler您尝试使用登录请求是Web API middeware的一部分,从来没有达到,因为令牌发布中间件处理该请求并没有进一步调用中间件酝酿中。

代替使用DelegatingHandler,使用以下中间件,并将其安装在令牌中间件之前。

public class RequestLoggerMiddleware
{
    private readonly Func<IDictionary<string, object>, Task> _next;
    private readonly ILogger _logger;

    public RequestLoggerMiddleware(
        Func<IDictionary<string, object>, Task> next, 
        ILogger logger)
    {
        _next = next;
        _logger = logger;
    }

    public Task Invoke(IDictionary<string, object> environment)
    {
        var context = new OwinContext(environment);

        _logger.Write($"{context.Request.Method} {context.Request.Uri.AbsoluteUri}");
        var result = _next.Invoke(environment);
        _logger.Write($"Status code: {context.Response.StatusCode}");

        return result;
    }
}
Run Code Online (Sandbox Code Playgroud)

要安装中间件,只需插入语句:app.Use(typeof (RequestLoggerMiddleware));在之前,app.UseOAuthBearerTokens在你的声明Startup.cs