Freigeben über


401 Unbefugte Fehler in ASP.NET Core Web API mit Microsoft Entra ID

Wenn Sie eine ASP.NET Core Web API aufrufen, die mithilfe der Microsoft Entra ID-Authentifizierung gesichert ist, tritt möglicherweise ein Fehler "401 Nicht autorisiert" auf. Dieser Artikel enthält Anleitungen für die Verwendung von JwtBearerEvents zur Erfassung detaillierter Protokolle, um diese Fehler zu beheben.

Symptome

Sie verwenden das [Authorize] Attribut, um Ihre ASP.NET Core Web-API wie folgt zu sichern:

[Authorize]
public class MyController : ControllerBase
{
    ...
}

Oder


public class MyController : ControllerBase
{
   [Authorize]
   public ActionResult<string> Get(int id)
   {
       return "value";
   }
   ...
}

Wenn Sie die Web-API aufrufen, wird eine Antwort "401 Nicht autorisiert" zurückgegeben, die Meldung enthält jedoch keine Fehlerdetails.

Ursache

Die API gibt in den folgenden Szenarien möglicherweise eine Antwort "401 Nicht autorisiert" zurück:

  • Die Anforderung enthält keinen gültigen Tokenheader "Authorization: Bearer".
  • Das Token ist abgelaufen oder falsch:

Lösung

Verwenden Sie zum Debuggen und Beheben von Fehlern "401 Nicht autorisiert" die JwtBearerEvents Rückrufe, um detaillierte Fehlerinformationen zu erfassen und zu protokollieren. Führen Sie die folgenden Schritte aus, um einen benutzerdefinierten Fehlerbehandlungsmechanismus zu implementieren.

Die JwtBearerEvents Klasse verfügt über die folgenden Rückrufeigenschaften (in der folgenden Reihenfolge aufgerufen), die Ihnen beim Debuggen dieser Probleme "401 Zugriff verweigert" oder "UnAuthorization" helfen können:

  • OnMessageRecieved wird zuerst für jede Anforderung aufgerufen.
  • OnAuthenticationFailed wird aufgerufen, wenn das Token die Tokenüberprüfungskriterien der Anwendung nicht erfüllt.
  • OnChallenge wird zuletzt aufgerufen, bevor eine "401"-Antwort zurückgegeben wird.

Schritt 1: Aktivieren der PII-Protokollierung

Standardmäßig ist die PII-Protokollierung deaktiviert. Aktivieren Sie sie in der Configure-Methode der Startup.cs-Datei für das Debuggen.

Vorsicht

Verwenden Sie "Microsoft.IdentityModel.Logging.IdentityModelEventSource.ShowPII = true" nur in einer Entwicklungsumgebung für das Debuggen. Verwenden Sie sie nicht in einer Produktionsumgebung.

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        // The default HSTS value is 30 days. You might want to change this value for production scenarios. See https://aka.ms/aspnetcore-hsts.
        app.UseHsts();
    }
    // turn on PII logging
    Microsoft.IdentityModel.Logging.IdentityModelEventSource.ShowPII = true;

    app.UseHttpsRedirection();
    app.UseAuthentication();
    app.UseMvc();
}  

Schritt 2: Erstellen einer Hilfsmethode zum Formatieren von Ausnahmemeldungen

Fügen Sie eine Methode zum Formatieren hinzu, und flachen Sie alle Ausnahmemeldungen, um die Lesbarkeit zu verbessern:

public static string FlattenException(Exception exception)
{
    var stringBuilder = new StringBuilder();
    while (exception != null)
    {
        stringBuilder.AppendLine(exception.Message);
        stringBuilder.AppendLine(exception.StackTrace);
        exception = exception.InnerException;
    }
    return stringBuilder.ToString();
}

Schritt 3: Implementieren von JwtBearerEvents-Rückrufen

Konfigurieren Sie die JwtBearerEvents Rückrufe in der ConfigureServices Methode von Startup.cs für die Behandlung von Authentifizierungsereignissen und Protokollfehlerdetails:

public void ConfigureServices(IServiceCollection services)
{
....
    .AddJwtBearer(options =>
    {
        options.Authority = "https://login.microsoftonline.com/<Tenant>.onmicrosoft.com";
        // if you intend to validate only one audience for the access token, you can use options.Audience instead of
        // using options.TokenValidationParameters which allow for more customization.
        // options.Audience = "10e569bc5-4c43-419e-971b-7c37112adf691";

        options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
        {
            ValidAudiences = new List<string> { "<Application ID URI>", "10e569bc5-4c43-419e-971b-7c37112adf691" },
            ValidIssuers = new List<string> { "https://sts.windows.net/<Directory ID>/", "https://sts.windows.net/<Directory ID>/v2.0" }
        };
                
        options.Events = new JwtBearerEvents
        {
            OnAuthenticationFailed = ctx =>
            {
                ctx.Response.StatusCode = StatusCodes.Status401Unauthorized;
                message += "From OnAuthenticationFailed:\n";
                message += FlattenException(ctx.Exception);
                return Task.CompletedTask;
            },

            OnChallenge = ctx =>
            {
                message += "From OnChallenge:\n";
                ctx.Response.StatusCode = StatusCodes.Status401Unauthorized;
                ctx.Response.ContentType = "text/plain";
                return ctx.Response.WriteAsync(message);
            },

            OnMessageReceived = ctx =>
            {
                message = "From OnMessageReceived:\n";
                ctx.Request.Headers.TryGetValue("Authorization", out var BearerToken);
                if (BearerToken.Count == 0)
                    BearerToken = "no Bearer token sent\n";
                message += "Authorization Header sent: " + BearerToken + "\n";
                return Task.CompletedTask;
            },
#For completeness, the sample code also implemented the OnTokenValidated property to log the token claims. This method is invoked when authentication is successful
            OnTokenValidated = ctx =>
            {
                Debug.WriteLine("token: " + ctx.SecurityToken.ToString());
                return Task.CompletedTask;
            }
        };
    });
...
}

Bespielergebnisse

Wenn Sie JwtBearerEvents Rückrufe implementieren, wenn ein Fehler "401 Nicht autorisiert" auftritt, sollte die Antwortausgabe Details wie im folgenden Beispiel enthalten:

OnMessageRecieved:

Authorization Header sent: no Bearer token sent.

Wenn Sie das API-Entwicklungstool zum Debuggen der Anforderung verwenden, sollten Sie Fehlerdetails erhalten, wie im folgenden Screenshot gezeigt.

Screenshot der Fehlerdetails im API-Entwicklungstool.

Kontaktieren Sie uns für Hilfe

Wenn Sie Fragen haben oder Hilfe benötigen, erstellen Sie eine Support-Anfrage oder wenden Sie sich an den Azure Community-Support. Sie können auch Produktfeedback an die Azure Feedback Community senden.