我们如何在 ASP.NET Web API 中记录身份验证令牌请求
How do we log authentication token requests in ASP.NET Web API
我们有一个 ASP.NET Web Api 应用程序,它使用 OAuth Bearer Tokens 进行身份验证,我们正在尝试为此实现 Request/Response 日志记录。
基本上它是这样工作的:
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);
}
使用 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")
});
}
}
}
您正在安装 OWIN middleware 以在 WebAPI 中间件之前 发行令牌。
app.UseOAuthBearerTokens(new OAuthAuthorizationServerOptions
{
Provider = new ApplicationAuthProvider(),
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/Authenticate")
});
您尝试用来记录请求的 DelegatingHandler
是 Web API 中间件的一部分并且永远不会到达,因为令牌发布中间件处理请求并且不会在管道。
不要使用 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;
}
}
要安装中间件,只需在 Startup.cs
.
中的 app.UseOAuthBearerTokens
语句之前插入语句:app.Use(typeof (RequestLoggerMiddleware));
我们有一个 ASP.NET Web Api 应用程序,它使用 OAuth Bearer Tokens 进行身份验证,我们正在尝试为此实现 Request/Response 日志记录。
基本上它是这样工作的:
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);
}
使用 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")
});
}
}
}
您正在安装 OWIN middleware 以在 WebAPI 中间件之前 发行令牌。
app.UseOAuthBearerTokens(new OAuthAuthorizationServerOptions
{
Provider = new ApplicationAuthProvider(),
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/Authenticate")
});
您尝试用来记录请求的 DelegatingHandler
是 Web API 中间件的一部分并且永远不会到达,因为令牌发布中间件处理请求并且不会在管道。
不要使用 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;
}
}
要安装中间件,只需在 Startup.cs
.
app.UseOAuthBearerTokens
语句之前插入语句:app.Use(typeof (RequestLoggerMiddleware));