# MiniAuth
**Repository Path**: mofees/MiniAuth
## Basic Information
- **Project Name**: MiniAuth
- **Description**: MiniAuth 轻量 ASP.NET Core Identity Web 后台管理插件
- **Primary Language**: C#
- **License**: Apache-2.0
- **Default Branch**: main
- **Homepage**: https://github.com/mini-software/MiniAuth
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 26
- **Created**: 2024-08-13
- **Last Updated**: 2024-08-13
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
---
---
### Introduction
"One-line code" adds asp.net core identity user/role management web for your new/old projects
### Features
- Compatibility: Supports .NET identity Based on JWT, Cookie, Session, etc.
- Simple: Plug-and-play design, API, MVC, Razor Page, etc.
- Supports multiple databases: Supports Oracle, SQL Server, MySQL, etc. EF Core
- Non-intrusive: Does not affect existing databases or project structures
- Multi-platform: Supports Linux, macOS environments
### Installation
Install the package from NuGet
```
```
### Quick Start
Add a single line of code `services.AddMiniAuth()` in Startup, then run your project. Example:
```csharp
public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddMiniAuth(); // <= ❗❗❗
var app = builder.Build();
app.Run();
}
}
```
The default admin account is `admin@mini-software.github.io` with the password `E7c4f679-f379-42bf-b547-684d456bc37f` (remember to change the password). The admin page can be accessed at `http(s)://yourhost/miniauth/index.html`.
Add `[Authorize]` to categories or methods that require permission management, or role control `[Authorize(Roles = "role")]`, return 401 status if not logged in, and return 403 status if no permission.
### MiniAuth Cookie Identity
MiniAuth is preset as a single Coookie Based identity, please change to JWT, etc. Auth for front-end and back-end separation projects.
### MiniAuth JWT Identity
Setting AuthenticationType = BearerJwt
```C#
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddMiniAuth(options:(options) =>
{
options.AuthenticationType = MiniAuthOptions.AuthType.BearerJwt;
});
```
Please remember to set new JWT Security Key, e.g.
```C#
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddMiniAuth(options: (options) =>
{
options.JWTKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("6ee3edbf-488e-4484-9c2c-e3ffa6dcbc09"));
});
```
#### Getting token
Frontend Javascript XHR example
```javascript
var data = JSON.stringify({
"username": "admin@mini-software.github.io",
"password": "E7c4f679-f379-42bf-b547-684d456bc37f",
"remember": false
});
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
xhr.addEventListener("readystatechange", function() {
if(this.readyState === 4) {
console.log(this.responseText);
}
});
xhr.open("POST", "http://yourhost/miniauth/login");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.send(data);
```
response
```json
{
"ok": true,
"code": 200,
"message": null,
"data": {
"tokenType": "Bearer",
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1laWQiOiIxZTIxOGY4My1iZjE3LTRhY2YtODhmOS1iOTQ3NjhjOWUwMGMiLCJuYW1lIjoiYWRtaW5AbWluaS1zb2Z0d2FyZS5naXRodWIuaW8iLCJyb2xlIjoibWluaWF1dGgtYWRtaW4iLCJzdWIiOiJhZG1pbkBtaW5pLXNvZnR3YXJlLmdpdGh1Yi5pbyIsIm5iZiI6MTcxODIwNDg5NSwiZXhwIjoxNzE4MjA1Nzk1LCJpYXQiOjE3MTgyMDQ4OTUsImlzcyI6Ik1pbmlBdXRoIn0._-DQ_rcbeju8_nrK2lD5we0rre04_xdDZNF6NhM0Rg0",
"expiresIn": 900
}
}
```
Save the `accessToken` in localstorage or a cookie. When calling your [Authorize] API, set the `Header Authorization` to `Bearer + space + accessToken`, and the system will automatically verify it.
Example:
```js
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
xhr.addEventListener("readystatechange", function() {
if(this.readyState === 4) {
console.log(this.responseText);
}
});
xhr.open("GET", "http://yourhost:5014/your/api");
xhr.setRequestHeader("Authorization", "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1laWQiOiIxZTIxOGY4My1iZjE3LTRhY2YtODhmOS1iOTQ3NjhjOWUwMGMiLCJuYW1lIjoiYWRtaW5AbWluaS1zb2Z0d2FyZS5naXRodWIuaW8iLCJyb2xlIjoibWluaWF1dGgtYWRtaW4iLCJzdWIiOiJhZG1pbkBtaW5pLXNvZnR3YXJlLmdpdGh1Yi5pbyIsIm5iZiI6MTcxODIwNDg5NSwiZXhwIjoxNzE4MjA1Nzk1LCJpYXQiOjE3MTgyMDQ4OTUsImlzcyI6Ik1pbmlBdXRoIn0._-DQ_rcbeju8_nrK2lD5we0rre04_xdDZNF6NhM0Rg0");
xhr.send();
```
#### Set Expiration Time
```c#
options.TokenExpiresIn = 30 * 60;
```
The unit is in seconds, with a default setting of 30 minutes. Additionally, note that .NET JWT ClockSkew in JwtBearerOptions is preset to add an extra 5 minutes [reason](https://stackoverflow.com/questions/43045035/jwt-token-authentication-expired-tokens-still-working-net-core-web-api).
#### Refresh Token API (JWT)
API : `/MiniAuth/refreshToken`
Body:
```json
{
"refreshToken":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxZTIxOGY4My1iZjE3LTRhY2YtODhmOS1iOTQ3NjhjOWUwMGMiLCJuYmYiOjE3MTg1MjIxOTEsImV4cCI6MTcxODUyMzk5MSwiaWF0IjoxNzE4NTIyMTkxLCJpc3MiOiJNaW5pQXV0aCJ9.HYBWrM2suDiM4OG0FSlXhNgktZIG9l3ufmIAnwZiIoU"
}
```
Header:
```
Authorization:Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiYWRtaW5AbWluaS1zb2Z0d2FyZS5naXRodWIuaW8iLCJyb2xlIjoibWluaWF1dGgtYWRtaW4iLCJzdWIiOiIxZTIxOGY4My1iZjE3LTRhY2YtODhmOS1iOTQ3NjhjOWUwMGMiLCJuYmYiOjE3MTg1MjIxOTEsImV4cCI6MTcxODUyNTc5MSwiaWF0IjoxNzE4NTIyMTkxLCJpc3MiOiJNaW5pQXV0aCJ9.rgAgsziAdLqOC9NYra-M9WQl8BJ99sRdfzRKNkMz9dk
```
The expiration time is set to `MiniAuthOptions.TokenExpiresIn / 2`, with a default of 30 minutes.
### Settings, Options, Customization
#### Default Mode
- The default mode of MiniAuth is centralized user management by IT Admins. Operations such as user registration and password reset require an admin account with the predefined role = miniauth-admin.
#### Disable MiniAuth Login
If you only want to use your own login logic, pages, and APIs, you can specify the login path and disable the MiniAuth login switch.
```C#
// Place before service registration
builder.Services.AddMiniAuth(options: (options) =>
{
options.LoginPath = "/Identity/Account/Login";
options.DisableMiniAuthLogin = true;
});
```
#### Customize Default SQLite Connection String
```C#
builder.Services.AddMiniAuth(options: (options) =>
{
options.SqliteConnectionString = "Data Source=miniauth_identity.db";
});
```
### Custom Database, Users, and Roles
MiniAuth is designed to work seamlessly with SQLite EF Core, IdentityUser, and IdentityRole by default. If you need to switch, please specify different databases and your own user and role classes using generics in `app.UseMiniAuth`.
```C#
app.UseMiniAuth();
```
### Login, User Authentication
For non-ApiController, the default login redirection is to the login.html page (determined by checking if Headers["X-Requested-With"] == "XMLHttpRequest" or the presence of the ApiControllerAttribute).
Controllers marked as ApiController do not redirect to a login page by default; instead, they return a 401 status code.
### Custom Frontend
- The admin dashboard frontend is located in `/src/Frontend_Identity` and primarily uses Vue3 + Vite. Running `npm run build` will update the miniauth UI.
- If you don't want to use the default miniauth login page, MVC allows you to use the scaffolded Login.cshtml provided by identity, or you can modify the login.html, js, and css files in the miniauth frontend.
### Custom Route Prefix
```
builder.Services.AddMiniAuth(options: (options) =>
{
options.RoutePrefix = "YourName";
});
```
The default RoutePrefix is `MiniAuth`.
### Login API (JWT)
API: `/MiniAuth/login`
Body:
```json
{
"username":"admin@mini-software.github.io",
"password":"E7c4f679-f379-42bf-b547-684d456bc37f",
"remember":false
}
```
Response:
```json
{
"ok": true,
"code": 200,
"message": null,
"data": {
"tokenType": "Bearer",
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiYWRtaW5AbWluaS1zb2Z0d2FyZS5naXRodWIuaW8iLCJyb2xlIjoibWluaWF1dGgtYWRtaW4iLCJzdWIiOiIxZTIxOGY4My1iZjE3LTRhY2YtODhmOS1iOTQ3NjhjOWUwMGMiLCJuYmYiOjE3MTg1MjIxOTEsImV4cCI6MTcxODUyNTc5MSwiaWF0IjoxNzE4NTIyMTkxLCJpc3MiOiJNaW5pQXV0aCJ9.rgAgsziAdLqOC9NYra-M9WQl8BJ99sRdfzRKNkMz9dk",
"expiresIn": 3600,
"refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxZTIxOGY4My1iZjE3LTRhY2YtODhmOS1iOTQ3NjhjOWUwMGMiLCJuYmYiOjE3MTg1MjIxOTEsImV4cCI6MTcxODUyMzk5MSwiaWF0IjoxNzE4NTIyMTkxLCJpc3MiOiJNaW5pQXV0aCJ9.HYBWrM2suDiM4OG0FSlXhNgktZIG9l3ufmIAnwZiIoU"
}
}
```
### Registration
Please use the built-in registration API and pages provided by ASP.NET Core Identity.
### Forgot Password
Please use the built-in forgot password API and pages provided by ASP.NET Core Identity.
### Get User Information
Please utilize the built-in APIs and pages provided by ASP.NET Core Identity to retrieve user information. Note that you may need to implement additional logic or endpoints to expose the required user data, depending on your specific application needs. ASP.NET Core Identity provides a robust framework for managing user information, including profile data, roles, and claims.
### Notes
#### Attention to Order
Please place UseMiniAuth after route generation, otherwise, the system cannot obtain routing data for permission checks, as follows:
```c#
app.UseRouting();
app.UseMiniAuth();
```
#### Attention: Please Add Role Rules
Please add `AddRoles()`, otherwise `[Authorize(Roles = "permission")]` will not take effect.
```C#
builder.Services.AddDefaultIdentity(options => options.SignIn.RequireConfirmedAccount = true)
.AddRoles() // ❗❗❗
.AddEntityFrameworkStores();
```
### Integrating MiniAuth into an Existing Identity Project with Custom Logic
Disable AddMiniAuth's autoUse, and place UseMiniAuth after your own authentication, replacing the generic parameters with your own IdentityDBContext, user, and permission authentication. Here's an example:
```csharp
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection") ?? throw new InvalidOperationException("Connection string 'DefaultConnection' not found.");
builder.Services.AddDbContext(options =>
options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddDefaultIdentity(options => options.SignIn.RequireConfirmedAccount = true)
.AddRoles()
.AddEntityFrameworkStores();
builder.Services.AddControllersWithViews();
builder.Services.AddMiniAuth(autoUse: false); // <= ❗❗❗
var app = builder.Build();
app.UseMiniAuth(); // <= ❗❗❗
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.MapRazorPages();
app.Run();
}
```
This allows you to switch between using your own users, roles, database, and Identity logic.
#### Distributed Systems
- For database sources, consider switching to databases like SQL Server, MySQL, PostgreSQL, etc.
- It is recommended to switch to authentication methods like JWT for better integration in a distributed environment.
### Release Notes
Refer to the [Release Notes](releases) for updates.
### TODO
Link: [MiniAuth.Identify project](https://github.com/orgs/mini-software/projects/7/views/1)