OAuth Authentication With Individual User Accounts in ASP.NET Core 6
Some time ago I wrote an article about OAuth authentication in ASP.NET Core 2.2, using the third party library OpenIddict to implement the authentication middleware.
Since then new versions of .NET has come and current version is .NET 6.
For this reason I decided to rework the “old” solution and create a new version of it, using the latest ASP.NET version available.
I’ve prepared a Github repository with a .NET 6 project with all necessary configurations already in place.
You can clone this project and use it as a starting point for any application with an API that needs OAuth authentication.
Once you have downloaded and compiled the code, you can start the application and call the /api/account/register
endpoint to register an account and the /auth/token
endpoint to exchange your credentials with an access token to use for authorized access to secure API endpoints.
The Database Provider
I used EntityFramework Core SQLite provider for this project, since it’s lighweight and portable, but you can easily switch to SQL Server if you need, the code would be almost identical.
To switch to SQL Server you only need to:
- Change the connection string in
appsettings.json
file - Install the Entityframework Core SQL Server NuGet package (and uninstall the SQLite version)
- Change all places in code where there are explicit references to SQLite provider’s methods, in order to use the same methods from the SQL Server package
Usage Example
Create a Secure Controller
You can create a controller with a secure endpoint with a code like this:
[Route("api/[controller]")]
[ApiController]
public class ItemsController : AuthControllerBase
{
private readonly IItemRepository _itemRepo;
public ItemsController(
UserManager<AppUser> userManager,
IItemRepository itemRepo
) : base(userManager)
{
_itemRepo = itemRepo;
}
[HttpGet]
[AllowAnonymous]
public List<Item> Get() => Try(() =>
{
return _itemRepo.GetAll().ToList();
});
[HttpPost]
public Item Add([FromBody] Item item) => Try(() =>
{
_itemRepo.Add(item);
_itemRepo.Commit();
return item;
/});
[HttpDelete("{id}")]
public IActionResult Delete(Guid id) => Try(() =>
{
_itemRepo.Delete(_ => _.Id == id);
return Ok();
});
}
The above example makes use of a sample database repository IItemRepository
, but you can replace it with whatever you want.
Register an Account
You need to call the /api/account/register
endpoint to register a new user account:
curl --location --request POST '/api/account/register' \
--header 'Content-Type: application/json' \
--data-raw '{
"email": "user@domain.com",
"password": "ThisIsMyPassword"
}'
Get an Access Token
Once you created an account, you can call the /auth/token
endpoint to obtain an access token using your credentials:
curl --location --request POST '/auth/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'username=user@domain.com' \
--data-urlencode 'password=ThisIsMyPassword' \
--data-urlencode 'grant_type=password'
Call a Secure Endpoint
With a valid access token in your hands you can call a secure API endpoint putting the token in the Authorization request header, as per OAuth standard:
curl --location --request POST '/api/items' \
--header 'Authorization: Bearer <your_token>' \
--header 'Content-Type: application/json' \
--data-raw '{
"name": "Test Item"
}'
Conclusion
From here it’s all in your hands. You can now develop your next amazing API!