Skip to content

Commit b202dbd

Browse files
committed
refactor(documentation): update
1 parent bc7d930 commit b202dbd

40 files changed

Lines changed: 945 additions & 285 deletions

documentation/simplew/docs/.vitepress/config.mjs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,10 @@ export default defineConfig({
7272
]
7373
},
7474
{
75-
text: 'Extend',
75+
text: 'Extensibility',
7676
items: [
7777
{ text: 'Middleware', link: '/guide/middleware' },
78+
{ text: 'Attribute', link: '/guide/handler-attribute' },
7879
{ text: 'Module', link: '/guide/module' },
7980
{ text: 'Callback', link: '/guide/callback' },
8081
{ text: 'Result Handler', link: '/guide/resulthandler' },
@@ -87,7 +88,6 @@ export default defineConfig({
8788
{ text: 'Principal', link: '/guide/principal' },
8889
{ text: 'Cross-Origin Resource Sharing', link: '/guide/cors' },
8990
{ text: 'SSL Certificate', link: '/guide/ssl-certificate' },
90-
{ text: 'Basic Auth', link: '/guide/basicauth' },
9191
]
9292
},
9393
{
@@ -112,6 +112,7 @@ export default defineConfig({
112112
{
113113
text: 'Services',
114114
items: [
115+
{ text: 'BasicAuth', link: '/addons/service-basicauth' },
115116
{ text: 'Chaos', link: '/addons/service-chaos' },
116117
{ text: 'Firewall', link: '/addons/service-firewall' },
117118
{ text: 'Latency', link: '/addons/service-latency' },
@@ -122,6 +123,7 @@ export default defineConfig({
122123
{
123124
text: 'Helpers',
124125
items: [
126+
{ text: 'BasicAuth', link: '/addons/helper-basicauth' },
125127
{ text: 'Hosting', link: '/addons/helper-hosting' },
126128
{ text: 'Jwt', link: '/addons/helper-jwt' },
127129
{ text: 'Log4net', link: '/addons/helper-log4net' },
@@ -159,6 +161,7 @@ export default defineConfig({
159161
{ text: 'HttpBag', link: '/reference/httpbag' },
160162
{ text: 'HttpMiddleware', link: '/reference/httpmiddleware' },
161163
{ text: 'IHttpModule', link: '/reference/ihttpmodule' },
164+
{ text: 'ISimpleWEngine', link: '/reference/isimplewengine' },
162165
{ text: 'IJsonEngine', link: '/reference/ijsonengine' },
163166
{ text: 'IdentityProperty', link: '/reference/identityproperty' },
164167
]

documentation/simplew/docs/.vitepress/theme/components/AnimatedLogo.vue

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,9 @@
156156
--out-y-7: 55%;
157157
--out-y-8: 58%;
158158
159+
--label-x-factor: 0.35;
160+
--label-y-factor: 0.39;
161+
159162
width: min(100%, var(--scene-w));
160163
height: var(--scene-h);
161164
margin: 0 auto;
@@ -350,7 +353,10 @@
350353
Persistent orbit labels
351354
========================================================= */
352355
.belt-label {
356+
--label-ring-size: 0px;
353357
position: absolute;
358+
left: calc(50% + var(--label-ring-size) * var(--label-x-factor));
359+
top: calc(50% - var(--label-ring-size) * var(--label-y-factor));
354360
font-size: 10px;
355361
font-family: ui-monospace, monospace;
356362
letter-spacing: 0.07em;
@@ -362,20 +368,17 @@
362368
}
363369
364370
.label-firewall {
365-
left: calc(40% + var(--belt-fw) / 2 + 10px);
366-
top: calc(20% - 20px);
371+
--label-ring-size: var(--belt-fw);
367372
color: var(--fw-main);
368373
}
369374
370375
.label-auth {
371-
left: calc(40% + var(--belt-auth) / 2 + 10px);
372-
top: 20%;
376+
--label-ring-size: var(--belt-auth);
373377
color: var(--auth-main);
374378
}
375379
376380
.label-routing {
377-
right: calc(8% + var(--belt-routing) / 2 + 10px);
378-
top: calc(20% + 20px);
381+
--label-ring-size: var(--belt-routing);
379382
color: var(--routing-main);
380383
}
381384
@@ -941,9 +944,9 @@
941944
.server-core {
942945
--scene-h: 320px;
943946
--logo-size: 150px;
944-
--belt-routing: 136px;
945-
--belt-auth: 180px;
946-
--belt-fw: 230px;
947+
--belt-routing: 180px;
948+
--belt-auth: 230px;
949+
--belt-fw: 280px;
947950
--dot: 6px;
948951
}
949952
@@ -962,15 +965,16 @@
962965
width: 15px;
963966
height: 15px;
964967
}
968+
965969
}
966970
967971
@media (max-width: 640px) {
968972
.server-core {
969973
--scene-h: 236px;
970974
--logo-size: 110px;
971-
--belt-routing: 96px;
972-
--belt-auth: 126px;
973-
--belt-fw: 162px;
975+
--belt-routing: 126px;
976+
--belt-auth: 162px;
977+
--belt-fw: 198px;
974978
--dot: 5px;
975979
margin-bottom: -65px;
976980
}
@@ -994,6 +998,7 @@
994998
width: 13px;
995999
height: 13px;
9961000
}
1001+
9971002
}
9981003
9991004
/* =========================================================

documentation/simplew/docs/addons/addons.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ Templates allow developers to:
4848
They allow SimpleW to support different JSON serializers/deserializers, depending on performance needs, features, or external dependencies.
4949

5050
Each JsonEngine addon provides :
51-
- A concrete implementation of a JSON engine
51+
- A concrete implementation of a `IJsonEngine`
5252
- A consistent API that integrates with SimpleW’s configuration
5353

5454
This makes it easy to switch or extend JSON handling without impacting the rest of the system.
Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
# BasicAuth
2+
3+
The [`SimpleW.Helper.BasicAuth`](https://www.nuget.org/packages/SimpleW.Helper.BasicAuth) package provides a lightweight HTTP Basic authentication helper for SimpleW.
4+
5+
6+
## Features
7+
8+
This package is intentionally focused on the authentication engine only:
9+
- parse the `Authorization` header
10+
- validate a username/password pair
11+
- create a `HttpPrincipal`
12+
- send a `401` Basic challenge
13+
14+
It does **not** decide which routes must be protected.
15+
That policy stays in your own custom middleware, which makes this package a good fit for:
16+
- custom auth attributes based on `IHandlerMetadata`
17+
- controller-specific authorization rules
18+
- mixed authentication strategies chosen by the application
19+
20+
21+
## Requirements
22+
23+
- .NET 8.0
24+
- SimpleW (core server)
25+
26+
27+
## Installation
28+
29+
Install the package from NuGet:
30+
31+
```sh
32+
$ dotnet add package SimpleW.Helper.BasicAuth --version 26.0.0-rc.20260415-1732
33+
```
34+
35+
36+
## Configuration options
37+
38+
### BasicAuthHelper
39+
40+
| Method | Description |
41+
| ------ | ----------- |
42+
| `TryAuthenticate(session, out principal)` | Parses the `Authorization` header, validates credentials, and returns a `HttpPrincipal` when authentication succeeds. |
43+
| `SendChallengeAsync(session, realm)` | Sends a `401 Unauthorized` response with the `WWW-Authenticate` header for Basic auth. |
44+
45+
### BasicAuthOptions
46+
47+
| Option | Default | Description |
48+
| ------ | ------- | ----------- |
49+
| `Users` | empty | Static username/password list used when no custom validator is provided. |
50+
| `CredentialValidator` | `null` | Optional callback used to validate username/password pairs yourself. |
51+
| `PrincipalFactory` | built-in | Maps a successful authentication to a `HttpPrincipal`. |
52+
53+
### BasicAuthContext
54+
55+
| Property | Description |
56+
| -------- | ----------- |
57+
| `Session` | Current `HttpSession`. |
58+
| `Username` | Username extracted from the `Authorization` header. |
59+
| `Password` | Password extracted from the `Authorization` header. |
60+
61+
62+
## Minimal Example
63+
64+
This example shows the intended architecture:
65+
- a `BasicAuthHelper` handles the Basic auth protocol
66+
- a custom middleware reads handler metadata from `session.Metadata`
67+
- controllers decide which endpoints require authentication
68+
69+
```csharp
70+
using System.Net;
71+
using SimpleW;
72+
using SimpleW.Helper.BasicAuth;
73+
74+
var server = new SimpleWServer(IPAddress.Any, 2015);
75+
76+
// configure basic helper
77+
BasicAuthHelper basic = new(options => {
78+
options.Users = [
79+
new BasicUser("admin", "secret")
80+
];
81+
});
82+
83+
// use the basic helper in a custom auth middleware
84+
server.UseMiddleware(async (session, next) => {
85+
86+
// fast path for anonymous
87+
if (session.Metadata.Has<AllowAnonymousAttribute>()) {
88+
await next().ConfigureAwait(false);
89+
return;
90+
}
91+
92+
// fast path if not basic attribute
93+
BasicAuthAttribute? auth = session.Metadata.Get<BasicAuthAttribute>();
94+
if (auth == null) {
95+
await next().ConfigureAwait(false);
96+
return;
97+
}
98+
99+
// send challenge is not authenticate
100+
if (!basic.TryAuthenticate(session, out HttpPrincipal principal)) {
101+
await basic.SendChallengeAsync(session, auth.Realm).ConfigureAwait(false);
102+
return;
103+
}
104+
105+
// set the Session Principal with the principal found by basic helper
106+
session.Principal = principal;
107+
108+
await next().ConfigureAwait(false);
109+
});
110+
111+
server.MapController<AdminController>("/api");
112+
113+
await server.RunAsync();
114+
115+
[Route("/admin")]
116+
[BasicAuth("Admin Area")]
117+
public sealed class AdminController : Controller {
118+
119+
[Route("GET", "/me")]
120+
public object Me() {
121+
return new {
122+
user = Principal.Name
123+
};
124+
}
125+
126+
[AllowAnonymous]
127+
[Route("GET", "/health")]
128+
public object Health() {
129+
return new { ok = true };
130+
}
131+
132+
}
133+
134+
// definie a basic attribute
135+
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
136+
public sealed class BasicAuthAttribute : Attribute, IHandlerMetadata {
137+
138+
public BasicAuthAttribute(string realm = "Restricted") {
139+
Realm = realm;
140+
}
141+
142+
public string Realm { get; }
143+
144+
}
145+
146+
// define a Anonymous attribute
147+
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
148+
public sealed class AllowAnonymousAttribute : Attribute, IHandlerMetadata {
149+
}
150+
```
151+
152+
In this model:
153+
- the helper performs authentication
154+
- the middleware decides whether the current handler requires authentication thanks to custom attribute
155+
- the controller stays clean and only declares intent through metadata
156+
157+
158+
## Custom credential validation
159+
160+
Instead of a static users list, you can validate credentials yourself:
161+
162+
```csharp
163+
BasicAuthHelper basic = new(options => {
164+
options.CredentialValidator = (username, password) => {
165+
return username == "admin" && password == "secret";
166+
};
167+
});
168+
```
169+
170+
This is useful when credentials come from:
171+
- a database
172+
- a configuration provider
173+
- an external service
174+
175+
176+
## Custom principal mapping
177+
178+
You can fully control how an authenticated user becomes a `HttpPrincipal`:
179+
180+
```csharp
181+
BasicAuthHelper basic = new(options => {
182+
options.Users = [
183+
new BasicUser("admin", "secret")
184+
];
185+
186+
options.PrincipalFactory = context => {
187+
return new HttpPrincipal(new HttpIdentity(
188+
isAuthenticated: true,
189+
authenticationType: "Basic",
190+
identifier: context.Username,
191+
name: context.Username,
192+
email: null,
193+
roles: [ "admin" ],
194+
properties: [
195+
new IdentityProperty("login", context.Username),
196+
new IdentityProperty("source", "basic-auth")
197+
]
198+
));
199+
};
200+
});
201+
```
202+
203+
204+
## Integration Summary
205+
206+
| Step | Responsibility |
207+
| ---- | -------------- |
208+
| Parse Basic auth header | `BasicAuthHelper` |
209+
| Validate credentials | `BasicAuthHelper` |
210+
| Build `HttpPrincipal` | `BasicAuthHelper` |
211+
| Decide whether auth is required | your middleware |
212+
| Declare route intent | your `IHandlerMetadata` attributes |
213+
214+
215+
## Security Notes
216+
217+
- HTTP Basic credentials are only base64-encoded, not encrypted
218+
- Always use HTTPS in production
219+
- Keep realms explicit so browser prompts stay understandable
220+
- Treat `CredentialValidator` and `PrincipalFactory` as trusted application code
221+
222+
223+
## When to use the service package instead
224+
225+
If you only need simple prefix-based protection such as:
226+
- `/admin`
227+
- `/metrics`
228+
- `/internal`
229+
230+
and you do not need custom handler metadata, use [`SimpleW.Service.BasicAuth`](./service-basicauth.md) instead.
231+
232+
That package is a thin module built on top of this helper.

documentation/simplew/docs/addons/helper-hosting.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ It allows you to :
3535
Install the package from NuGet:
3636

3737
```sh
38-
$ dotnet add package SimpleW.Helper.Hosting --version 26.0.0-rc.20260405-1683
38+
$ dotnet add package SimpleW.Helper.Hosting --version 26.0.0-rc.20260415-1732
3939
```
4040

4141

0 commit comments

Comments
 (0)