Exelor is a lightweight .net core api framework that includes jwt authentication with refresh token support, permission authorisation, auditing, logging, error handling, fluent validation, data shaping and rate limiting with Open API spec via swagger
- .NET Core 3.0
- Fluent Validation
- MediatR
- Entity Framework Core.
- Swashbuckle.AspNetCore for Swagger
- ASP.NET Core JWT Bearer Authentication for JWT authentication with support for refresh tokens.
- Serilog for logging
- AspNetCoreRateLimit to add rate limiting functionality
- Sieve to add paging, sorting and filtering functionality
Authentication in Exelor is done by issuing an access token with the users claims in it. You'll need to login to the application with a username and password and if successful, you'll get an access token that is valid
for 15 minutes along with a refresh token that is valid for 2 days. You'll get a 401 response with a Token-Expired
header when the Jwt token is no longer valid. You can ask for a new token from the refreshtoken endpoint.
By default all routes in Exelor needs to be authorised. If you don't want a specific route to authorised, say registering a new user, you need to add [AllowAnonymous]
attribute to that route. Exelor supports permissions based authorisation, the access token that is issued contains the permissions claims which is used for authorisation.
You can authorise an action in 3 different ways
- Attribute based authorisation: You can add
HasPermission
attribute to controllers/actions and provide a list of permission which has access to the controllers/actions
[HttpGet]
[HasPermission(Permissions.ReadUsers, Permissions.EditUsers)]
public async Task> Get(
SieveModel sieveModel)
{
return await _mediator.Send(new UserList.Query(sieveModel));
}
- By checking if the user has a permission by calling
IsAllowed
[HttpPut]
public async Task Edit(
[FromBody] UpdateUser.Command command)
{
if (!_currentUser.IsAllowed(Permissions.EditUsers))
throw new HttpException(HttpStatusCode.Forbidden);
return await _mediator.Send(command);
}
- By validating a permission against the user (this throws an exception if the user doesn't have the permission in question)
[HttpDelete("{id}")]
public async Task Delete(
int id)
{
_currentUser.Authorize(Permissions.EditUsers);
await _mediator.Send(new DeleteUser.Command(id));
}
- You can enable auditing of entities which will log changes done on entities to the database. This table will store who made the changes, the table on which the change was made, the key of the entity that was changed, old values before the change and new values after
- You can use paging, sorting and filtering by using the Sieve model on Get endpoints which supports the following params (you can read more about Sieve here)
GET /GetPosts
?sorts= LikeCount,CommentCount,-created // sort by likes, then comments, then descendingly by date created
&filters= LikeCount>10, Title@=awesome title, // filter to posts with more than 10 likes, and a title that contains the phrase "awesome title"
&page= 1 // get the first page...
&pageSize= 10 // ...which contains 10 posts
- You can request the fields that you are interested in and only those fields are returned in the response
GET /Roles
?fields= Id, Name // Only returns the Id and Name values
[
{
"Id": 1,
"Name": "HR"
},
{
"Id": 2,
"Name": "Project Manager"
}
]
Install .NET Core SDKGo to exelor folder and rundotnet restore
anddotnet build
Add and run migrations-Install-ef
tool by runningdotnet tool install --global dotnet-ef
Rundotnet ef migrations add Init
and thendotnet ef database update
Rundotnet run
to start the server athttp://localhost:5000/
You can view the API reference athttp://localhost:5000/swagger
Login using{ "userName": "john", "password": "test" }
for ReadUsers permission and{ "userName": "jane", "password": "test" }
for SuperUser permission
- Add and run migrations
- Install
ef
tool by runningdotnet tool install --global dotnet-ef
- Run
dotnet ef migrations add "Init" --project Infrastructure --startup-project Web --output-dir Persistence\Migrations
- Install
- Go to the root folder of the project and run
docker-compose up
- You can view the API reference at
http://localhost:5000/swagger
- Login using
{ "userName": "john", "password": "test" }
for ReadUsers permission and{ "userName": "jane", "password": "test" }
for SuperUser permission
DefaultConnection
:Server=exelor_db;Port=5432;Database=starter;Uid=su;Pwd=YourStrong!Passw0rd
- Postgres connection string, a default database called starter is created when you run migrations
SecurityKey
:A super secret long key to encrypt and decrypt the token
Issuer
:Issuer
Audience
:Audience
- The key, issuer and audience values to generate a jwt token
Key
:Secret key to encrypt passwords
- The key to encrypt the passwords
Enabled
:true
- This is to enable or disable logging changes on the entities to Audits table
MinimumLevel
:"Default": "Information"
WriteTo
:"Name": "Console"
- Configure serilog options. Check wiki for more options and modifyappsettings.json
IpWhitelist
:[ "127.0.0.1", "::1/10", "192.168.0.0/24" ]
GeneralRules
:...
- Configure IpRateLimiting options. Localhost is whitelisted by default. Check wiki for more options and modifyappsettings.json
Sieve
:"CaseSensitive": false, "DefaultPageSize": 50, "MaxPageSize": 100, "ThrowExceptions": true
- Default options for Sieve which is used for paging, sorting and filtering
- Clone repo
git clone https://github.com/simplyvinay/exelor.git
- Create a new branch:
git checkout -b new_branch_name
- Make changes and test
- Submit Pull Request with description of changes