Skip to content

Commit 7355897

Browse files
authored
Improve logging for OIDC flow, fix HTTP 500 (#10662)
1 parent a3b1b5f commit 7355897

2 files changed

Lines changed: 28 additions & 3 deletions

File tree

src/NuGetGallery/Controllers/TokenApiController.cs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
using System.Net.Http.Headers;
88
using System.Threading.Tasks;
99
using System.Web.Mvc;
10+
using Microsoft.Build.Framework;
11+
using Microsoft.Extensions.Logging;
1012
using NuGetGallery.Authentication;
1113
using NuGetGallery.Services.Authentication;
1214

@@ -32,13 +34,16 @@ public class TokenApiController : AppController
3234

3335
private readonly IFederatedCredentialService _federatedCredentialService;
3436
private readonly IFederatedCredentialConfiguration _configuration;
37+
private readonly ILogger<TokenApiController> _logger;
3538

3639
public TokenApiController(
3740
IFederatedCredentialService federatedCredentialService,
38-
IFederatedCredentialConfiguration configuration)
41+
IFederatedCredentialConfiguration configuration,
42+
ILogger<TokenApiController> logger)
3943
{
4044
_federatedCredentialService = federatedCredentialService ?? throw new ArgumentNullException(nameof(federatedCredentialService));
4145
_configuration = configuration ?? throw new ArgumentNullException(nameof(configuration));
46+
_logger = logger;
4247
}
4348

4449
#pragma warning disable CA3147 // No need to validate Antiforgery Token with API request
@@ -86,6 +91,15 @@ public async Task<ActionResult> CreateToken(CreateTokenRequest request)
8691

8792
var result = await _federatedCredentialService.GenerateApiKeyAsync(request!.Username!, bearerToken!, Request.Headers);
8893

94+
if (result.Type == GenerateApiKeyResultType.Created)
95+
{
96+
_logger.LogInformation("Token creation request for user {Username} succeeded. API key expires at {Expiration:O}.", request.Username, result.Expires);
97+
}
98+
else
99+
{
100+
_logger.LogWarning("Token creation request for user {Username} failed with result type {ResultType}. User message: {UserMessage}", request.Username, result.Type, result.UserMessage);
101+
}
102+
89103
return result.Type switch
90104
{
91105
GenerateApiKeyResultType.BadRequest => ErrorJson(HttpStatusCode.BadRequest, result.UserMessage),
@@ -119,7 +133,15 @@ private JsonResult ErrorJson(HttpStatusCode status, string errorMessage)
119133
{
120134
// Show the error message in the HTTP reason phrase (status description) for compatibility with NuGet client error "protocol".
121135
// This, and the response body below, could be formalized with https://github.com/NuGet/NuGetGallery/issues/5818
122-
Response.StatusDescription = errorMessage;
136+
try
137+
{
138+
Response.StatusDescription = errorMessage;
139+
}
140+
catch
141+
{
142+
// Best effort: setting StatusDescription can fail based on the content of the error message.
143+
_logger.LogWarning("Failed to set StatusDescription to '{ErrorMessage}'", errorMessage);
144+
}
123145

124146
return Json(status, new { error = errorMessage });
125147
}

tests/NuGetGallery.Facts/Controllers/TokenApiControllerFacts.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
using NuGetGallery.Services.Authentication;
1919
using Xunit;
2020
using System.Text.Json;
21+
using Microsoft.Extensions.Logging;
2122

2223
#nullable enable
2324

@@ -266,6 +267,7 @@ public TokenApiControllerFacts()
266267
Identity = new Mock<IIdentity>();
267268
FederatedCredentialService = new Mock<IFederatedCredentialService>();
268269
Configuration = new Mock<IFederatedCredentialConfiguration>();
270+
Logger = new Mock<ILogger<TokenApiController>>();
269271

270272
RequestHeaders = new NameValueCollection();
271273
ResponseHeaders = new NameValueCollection();
@@ -287,7 +289,7 @@ public TokenApiControllerFacts()
287289
.Setup(x => x.GenerateApiKeyAsync(CreateTokenRequest.Username, BearerToken, RequestHeaders))
288290
.ReturnsAsync(() => GenerateApiKeyResult);
289291

290-
Target = new TokenApiController(FederatedCredentialService.Object, Configuration.Object);
292+
Target = new TokenApiController(FederatedCredentialService.Object, Configuration.Object, Logger.Object);
291293

292294
Target.SetOwinContextOverride(OwinContext.Object);
293295
Response.SetupProperty(x => x.StatusCode);
@@ -312,6 +314,7 @@ public TokenApiControllerFacts()
312314
public Mock<IIdentity> Identity { get; }
313315
public Mock<IFederatedCredentialService> FederatedCredentialService { get; }
314316
public Mock<IFederatedCredentialConfiguration> Configuration { get; }
317+
public Mock<ILogger<TokenApiController>> Logger { get; }
315318
public NameValueCollection RequestHeaders { get; }
316319
public NameValueCollection ResponseHeaders { get; }
317320
public string BearerToken { get; }

0 commit comments

Comments
 (0)