A shared web API project that contains all the core code necessary to build and secure a web API in .NET Core.
- Global Exception Handler with custom error message implementations.
- Swagger documentation simplification for .NET Core.
- JWT security integration with the
[Authorize]
annotation.
To install this library you can simply reference it as follows:
dotnet add package Shared.WebApi.Core
To utilize the global exception handler, you will need to the following:
- Create your own implementation of IErrorMessageSelector.
- Where applicable, create your own custom exception classes that extended BaseHttpException.
- There are also the following exceptions available:
- Register your implementation of
IErrorMessageSelector
inStartup.cs
in theConfigureServices
method as follows:services.TryAddTransient<IErrorMessageSelector, MyErrorMessageSelector>();
- Enable Global Exception Handling in the
Configure
method inStartup.cs
as follows:app.UseGlobalExceptionHandler();
- You should now be able to safely throw exceptions anywhere in your code base.
- Model validation or route/query parameter exceptions will automatically throw a BadRequestException.
- Various authentication exceptions will automatically throw either a ForbiddenException or an UnauthorizedException.
To use the Swagger documentation, including the XML documents from this library, you will need the following:
- Define the following constants in your
Startup.cs
:private const string ApiTitle = "My API"; private const int ApiVersion = 1; private const string ApiDescription = "My API description";
- In the
ConfigureServices
method in yourStartup.cs
, add the following code:// Set the comments path for the Swagger JSON and UI. var apiXmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; var apiXmlPath = Path.Combine(AppContext.BaseDirectory, apiXmlFile); // Use the builder to build the Swagger Services. new SwaggerServicesBuilder() .WithApiTitle(ApiTitle) .WithApiVersion(ApiVersion) .WithApiDescription(ApiDescription) .WithXmlComments(apiXmlPath) .WithCoreXmlDocs(true) // Set this to false if you wish to exclude the library comments. .WithJwtAuthentication(true) // Set this to false if you are not using JWT authentication. .BuildSwaggerServices(services);
- In the
Configure
method inStartup.cs
, add the following line of code:app.UseSwaggerDocs(ApiVersion, ApiTitle);
- To enable XML documentation from this library, you will need to modify your API project to include the Build.Directory.targets file. This file effectively copies the XML and PDB files from the various dependency NuGet packages you have referenced to your build directory.
-
For the controller actions you wish to protect through JWT security, decorate either the controller or each controller action with the
[Authorize]
annotation. -
In the
ConfigureServices
method inStartup.cs
, include token authentication as follows:services.AddTokenAuthentication(Configuration);
-
In the
Configure
method inStartup.cs
, include authorization by adding the following line:app.UseAuthorization();
-
Add a
JwtConfig
section to yourappsettings.json
- similar to the following:{ "JwtConfig": { "secret": "PDv7DrqznYL6nv7DrqzjnQYO9JxIsWdcjnQYL6nu0f", "expirationInMinutes": 60, "issuer": "localhost" } }
-
Over the controller action that will generate your token (such as a login, etc.), decorate that action with the
[AllowAnonymous]
annotation. -
For that same controller, add the following depedency to your constructor:
public Constructor(IJwtService jwtService) { _jwtService = jwtService; }
Ensure you introduce a private field
private readonly IJwtService _jwtService;
-
In the controller action that allows anonymous authentication, when you have validated the request, generate and return a token as follows:
var token = _jwtService.GenerateSecurityToken("fake@email.com"); return Ok(token);
In all, your code will look something like this:
/// <summary> /// A test API to resolve a JWT token. /// </summary> [Authorize] [Route("tokens")] public class TestTokensController : ControllerBase { private readonly IJwtService _jwtService; /// <summary> /// Initializes a new instance of the TestTokensController. /// </summary> /// <param name="jwtService">The JWT service.</param> public TestTokensController(IJwtService jwtService) { _jwtService = jwtService; } /// <summary> /// Generates a random JWT token. /// </summary> /// <returns>A random JWT token.</returns> [HttpGet] [AllowAnonymous] public IActionResult GetRandomToken() { var token = _jwtService.GenerateSecurityToken("fake@email.com"); return Ok(token); } }
To contribute to this project, please following the contributing guide.