In this article, we are going to look at how to implement swagger authorization in an ASP.Net Core Web API application.

We are only going to cover how to set up swagger to accept JSON Web Token (JWT) and how to utilize the token generated to access restricted resources in Swagger. That said, if you are not familiar with the JWT authentication, you can check out our articles ASP.NET Core Authentication One and ASP.NET Core Authentication Two for more information.

Additionally, for more information on configuring Swagger, you can visit our article Configuring and Using Swagger UI in ASP.NET Core.

To download the source code for this article, you can visit our GitHub repository.

Using the articles mentioned above as a guide, we have prepared a new ASP.NET Web API project and integrated swagger and JWT into it.

Overview of the ASP.NET Core Web API Project

Our app is going to be a straightforward product inventory.

Let’s take a look at the Product model:

public class Product
{
    public int Id { get; set; }
    public string? Name { get; set; }      
}

Next, we can find a ProductStore class that acts as a mock database:

public static class ProductStore
{
    private static Product[] products = new Product[]
    {
        new Product { Id = 1, Name = "Rubber duck"},
        new Product { Id = 2, Name = "Flip flop"},
        new Product { Id = 3, Name = "Magic Wand"},
        new Product { Id = 4, Name = "Glitter pen"}
    };

    public static IEnumerable<Product> GetProducts()
    {
        return products;
    }

    public static Product? GetProduct(int id)
    {
        foreach (var product in products)
        {
            if (product.Id == id)   
                return product;
        }
        return null;
    }
}

Following that, we have the ProductController that holds two action methods GetAllProducts and GetAProduct

public class ProductController : ControllerBase
{
    [HttpGet]
    public IActionResult GetAllProducts()
    {
        var products = ProductStore.GetProducts();
        return Ok(products);
    }
    
    [HttpGet("{id}")]
    public IActionResult GetAProduct(int id)
    {
        var product = ProductStore.GetProduct(id);

        if (product is null)
            return NotFound();

        return Ok(product);
    }
}

Finally, we have the AuthController that contains the Login action method: 

public class AuthController : ControllerBase
{
    [HttpPost, Route("login")]
    public IActionResult Login(LoginModel model)
    {
        if (model == null)
        {
            return BadRequest("Invalid client request");
        }

        if (model.UserName == "johndoe" && model.Password == "johndoe2410")
        {
            var secretKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("[email protected]"));
            var signinCredentials = new SigningCredentials(secretKey, SecurityAlgorithms.HmacSha256);

            var tokenOptions = new JwtSecurityToken(
                issuer: "CodeMaze",
                audience: "https://localhost:5001",
                claims: new List<Claim>(),
                expires: DateTime.Now.AddMinutes(5),
                signingCredentials: signinCredentials
            );

            var tokenString = new JwtSecurityTokenHandler().WriteToken(tokenOptions);
            return Ok(new { Token = tokenString });
        }
        else
        {
            return Unauthorized();
        }
    }
}

For the sake of keeping things simple, in the code above we’ve hardcoded the expected login credentials and security key. 

Adding the Authorize Attribute to an Action Method

We use the Authorize attribute when we want to restrict access to an action method and ensure that only authenticated users can access it.

So, let’s decorate our GetAllProducts action method with the Authorize attribute:

[HttpGet, Authorize]
public IActionResult GetAllProducts()
{
    var products = ProductStore.GetProducts();
    return Ok(products);
}      

After that, we can run the project and log in, and we are going to get a token:

Received Bearer token in Swagger

But when we try to access the GetAllProducts endpoint, we still get a 401 UnAuthorized error since we need to supply the generated bearer token to swagger to gain access.

So, let’s see how we can configure Swagger to accept bearer tokens and enable authorization with Swagger.

Configuring Authorization with Swagger – Accepting Bearer Token

To set up authorization with Swagger, we have to modify our Program.cs class, under the Swagger configuration:

builder.Services.AddSwaggerGen(opt =>
{
    opt.SwaggerDoc("v1", new OpenApiInfo { Title = "MyAPI", Version = "v1" });
    opt.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
    {
        In = ParameterLocation.Header,
        Description = "Please enter token",
        Name = "Authorization",
        Type = SecuritySchemeType.Http,
        BearerFormat = "JWT",
        Scheme = "bearer"
    });

    opt.AddSecurityRequirement(new OpenApiSecurityRequirement
    {
        {
            new OpenApiSecurityScheme
            {
                Reference = new OpenApiReference
                {
                    Type=ReferenceType.SecurityScheme,
                    Id="Bearer"
                }
            },
            new string[]{}
        }
    });
});

In the code, we added two extra SwaggerGenOptions. The AddSecurityDefinition action method tells swagger the type of protection we want for our API. It takes in the name of the security scheme and a security scheme definition. The AddSecurityRequirement action method adds the global security requirement.

Now when we run our app, we see an authorize button at the right-hand corner of our swagger user interface:

Authorize button in swagger UI

Let’s test this out.

Using Authorization with Swagger to Access Protected Resources

We’ll log in once again to get our bearer token.

After that, we are going to click the Authorize button, which is going to bring up the authorization modal:

Auth Modal to use token while executing authorization with Swagger

Let’s paste the generated token into the authorization modal’s input field, and then click Authorize and Close to dismiss the modal.

Now when we try to access the GetAllProducts endpoint we get a list of products from the ProductStore.

Using the generated token, we are able to get the authorization we need to access the protected GetAllProducts endpoint.

Conclusion

In this article, we have learned about:

  • Adding authorize attribute to our endpoint
  • How to configure the swagger user interface to accept bearer token
  • How to access protected resources by passing JWT to Swagger