Swagger AddSecurityRequirement Fails After Migrating from .NET 8 to .NET 10 — 401 Unauthorized on [Authorize] Endpoints

Tirth Shah 0 Reputation points
2025-12-04T18:12:28.19+00:00

Hello Team,

Hope you are doing well.

I previously had a working Swagger configuration in a .NET 8 Web API project. After migrating the project to .NET 10, the existing SwaggerGen and security configuration no longer compile.

Below is the original .NET 8 code snippet:

private static IServiceCollection AddSwagger(this IServiceCollection services)
{
    services.AddSwaggerGen(c =>
    {
        c.SwaggerDoc("v1", new OpenApiInfo { Title = "CMS API", Version = "v1" });

        c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
        {
            Description = @"JWT Authorization header using the Bearer scheme.
                            Enter 'Bearer' [space] and then your token.
                            Example: 'Bearer 12345abcdef'",
            Name = "Authorization",
            In = ParameterLocation.Header,
            Type = SecuritySchemeType.ApiKey,
            Scheme = "Bearer"
        });

        c.AddSecurityRequirement(new OpenApiSecurityRequirement
        {
            {
                new OpenApiSecurityScheme
                {
                    Reference = new OpenApiReference
                    {
                        Type = ReferenceType.SecurityScheme,
                        Id = "Bearer"
                    },
                    Scheme = "oauth2",
                    Name = "Bearer",
                    In = ParameterLocation.Header
                },
                Array.Empty<string>()
            }
        });
    });

    return services;
}

After migrating to .NET 10, the project shows the following compile-time error:

'Func<OpenApiDocument, OpenApiSecurityRequirement>' does not contain a constructor that takes 0 arguments
Object and collection initializer expressions may not be applied to a delegate creation expression

To fix the compile error, I updated the code as follows:

c.AddSecurityRequirement(document =>
{
    OpenApiSecuritySchemeReference? schemeRef = new("Bearer");
    OpenApiSecurityRequirement? requirement = new()
    {
        [schemeRef] = []
    };
    return requirement;
});

However, after applying this change, all [Authorize] endpoints return 401 Unauthorized even when I log in using a valid Bearer token.

Question: What is the correct way to configure AddSecurityRequirement in .NET 10 so Swagger works as expected and [Authorize] endpoints no longer return 401? Any updated examples or guidance for .NET 10 would be greatly appreciated.

Thank you,

Tirth Shah

Developer technologies | ASP.NET | ASP.NET Core
0 comments No comments
{count} votes

4 answers

Sort by: Most helpful
  1. Tom Tran (WICLOUD CORPORATION) 3,115 Reputation points Microsoft External Staff Moderator
    2025-12-05T09:44:48.9433333+00:00

    Hi @Tirth Shah ,

    Thanks for sharing the details!

    I see two things happening after your migration from .NET 8 to .NET 10:

    • The Swagger configuration fails to compile because AddSecurityRequirement now expects a delegate (Func<OpenApiDocument, OpenApiSecurityRequirement>).
    • Even after updating, [Authorize] endpoints return 401 Unauthorized, which usually points to middleware order or JWT settings rather than Swagger itself.

    I recommend you check these out first:


    1. Update Swagger configuration for .NET 10 and Swashbuckle v10

    Swashbuckle changed how security requirements are added. Define the HTTP Bearer scheme and use a delegate for the requirement:

    using Microsoft.OpenApi.Models;
     
    const string schemeId = "bearer";
    services.AddSwaggerGen(options =>
    {
        options.SwaggerDoc("v1", new OpenApiInfo { Title = "CMS API", Version = "v1" });
        options.AddSecurityDefinition(schemeId, new OpenApiSecurityScheme
        {
            Type = SecuritySchemeType.Http,
            Scheme = "bearer", // lowercase per RFC 7235
            BearerFormat = "JWT",
            Description = "JWT Authorization header using Bearer scheme"
        });
        options.AddSecurityRequirement(document =>
        {
            var requirement = new OpenApiSecurityRequirement
            {
                {
                    new OpenApiSecurityScheme
                    {
                        Reference = new OpenApiReference
                        {
                            Type = ReferenceType.SecurityScheme,
                            Id = schemeId
                        }
                    },
                    Array.Empty<string>() // no scopes for JWT
                }
            };
            return requirement;
        });
    });
    

    You can check Swashbuckle migration guide and OpenApiSecurityRequirement Class for better clarity.


    2. Check middleware order and JWT settings

    Make sure you call:

    app.UseSwagger();
    app.UseSwaggerUI();
    app.UseAuthentication();   // BEFORE endpoints
    app.UseAuthorization();
    // Then map endpoints
    app.MapControllers();      // or MapGroup/MapGet...
    

    before mapping endpoints. Then confirm your AddJwtBearer options match the token’s Issuer, Audience, and SigningKey. Full guidance here: Configure JWT bearer authentication in ASP.NET Core


    3. Use Swagger UI correctly

    Click Authorize, paste only the raw JWT (do not include Bearer, Swagger adds it automatically). Verify in the “Request” panel that the header shows Authorization: Bearer <token>.


    I also found this post that tackled similar issue, maybe you could check it out when you have the time:

    Disclaimer: Some of these links are non-Microsoft website. The pages appear to be providing accurate, safe information. Watch out for ads on the site that may advertise products frequently classifies as a PUP (Potentially Unwanted Products). Thoroughly research any product advertised on the site before you decide to download and install it.

    I hope this is helpful to you! If you have any more questions, please feel free to reach out. I'll be happy to help out!

    1 person found this answer helpful.
    0 comments No comments

  2. Q&A Assist
    2025-12-04T18:12:46.8033333+00:00
    AI generated content. This question contains an answer created with AI from Q&A Assist. Learn more

    To configure AddSecurityRequirement in .NET 10 correctly, you need to ensure that you are using the updated syntax for defining security requirements in Swagger. The error you encountered is likely due to the changes in the way security requirements are defined in .NET 10. Here’s how you can adjust your code:

    Updated Code Snippet for .NET 10

    private static IServiceCollection AddSwagger(this IServiceCollection services)
    {
        services.AddSwaggerGen(c =>
        {
            c.SwaggerDoc("v1", new OpenApiInfo { Title = "CMS API", Version = "v1" });
    
            c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
            {
                Description = @"JWT Authorization header using the Bearer scheme.\nEnter 'Bearer' [space] and then your token.\nExample: 'Bearer 12345abcdef'",
                Name = "Authorization",
                In = ParameterLocation.Header,
                Type = SecuritySchemeType.ApiKey,
                Scheme = "Bearer"
            });
    
            c.AddSecurityRequirement(new OpenApiSecurityRequirement
            {
                {
                    new OpenApiSecurityScheme
                    {
                        Reference = new OpenApiReference
                        {
                            Type = ReferenceType.SecurityScheme,
                            Id = "Bearer"
                        }
                    },
                    new string[] {}
                }
            });
        });
    
        return services;
    }
    

    Key Changes Explained:

    1. Security Requirement Definition: Ensure that the AddSecurityRequirement method is called with the correct parameters. In the updated example, we create an OpenApiSecurityRequirement directly, which includes the OpenApiSecurityScheme reference and an empty string array for scopes.
    2. Authorization Handling: If you are still receiving 401 Unauthorized responses, double-check that your Bearer token is valid and that the token is being sent correctly in the Authorization header of your requests. You may also want to enable detailed logging to capture any issues with token validation.

    Additional Steps for Debugging 401 Errors:

    • Ensure that the token is not expired and is intended for the resource you are accessing.
    • Use JwtBearerEvents to log detailed error information, which can help identify why the authorization is failing.

    By following these guidelines, you should be able to configure Swagger correctly in .NET 10 and resolve the 401 Unauthorized issues on your [Authorize] endpoints.


    References:


  3. Tirth Shah 0 Reputation points
    2025-12-05T10:18:03.7166667+00:00

    Hello @Tom Tran (WICLOUD CORPORATION)

    Thank you for assisting me with the Bearer token issue. I appreciate your support and guidance.

    Now, I have another project where I am not using the Bearer Token concept, but I am using the OAuth2 Concept, and in that, I am encountering the same issues. So, I must have made a mistake. Let me know. I am sharing that here. In the code below, I am getting the same 401 error, so let me know if I have made a mistake.

    services.AddSwaggerGen(c =>
    {
        c.SupportNonNullableReferenceTypes();
        c.SwaggerDoc(_apiVersion.VersionName,
            new()
            {
                Title = _apiVersion.Title,
                Version = _apiVersion.VersionNumber
            });
    
        // OAuth2 definition
        c.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
        {
            Type = SecuritySchemeType.OAuth2,
            Flows = new()
            {
                AuthorizationCode = new()
                {
                    AuthorizationUrl = new($"https://login.microsoftonline.com/{_azureAd.TenantId}/oauth2/v2.0/authorize"),
                    TokenUrl = new($"https://login.microsoftonline.com/{_azureAd.TenantId}/oauth2/v2.0/token"),
                    Scopes = new Dictionary<string, string>
                    {
                        { _azureAd.ApplicationUri, _azureAd.Scopes }
                    }
                }
            }
        });
    
        c.AddSecurityRequirement(document =>
        {
            OpenApiSecuritySchemeReference? schemeRef = new("oauth2");
            OpenApiSecurityRequirement? requirement = new()
            {
                [schemeRef] = []
            };
            return requirement;
        });
    });
    

  4. Gert Kello 0 Reputation points
    2025-12-05T19:17:36.5966667+00:00

    Struggled with similar upgrade issue, for me helped passing document in reference constructor:

         c.AddSecurityRequirement(document =>
         {
             OpenApiSecuritySchemeReference? schemeRef = new("oauth2", document);
    
    0 comments No comments

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.