Skip to content

Commit 8694661

Browse files
committed
Add v8.3 feature docs
1 parent 4de7b93 commit 8694661

File tree

3 files changed

+808
-0
lines changed

3 files changed

+808
-0
lines changed

MyApp/_pages/auth/admin-apikeys.md

Lines changed: 265 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,265 @@
1+
---
2+
title: Simple Auth for .NET 8 Apps
3+
---
4+
5+
With ServiceStack now fully [integrated with ASP.NET Identity Auth](/auth/identity-auth),
6+
our latest [.NET 8 Tailwind Templates](/start) offer a full-featured Auth Configuration complete with User Registration,
7+
Login, Password Recovery, Two Factory Auth, and more.
8+
9+
Whilst great for Web Applications that need it, it neglects the class of Apps which don't need User Auth and
10+
the additional complexity it brings inc. Identity and Password Management, EF Migrations, Token Expirations, OAuth Integrations, etc.
11+
12+
For these stand-alone Apps, Microservices and Docker Appliances that would still like to restrict Access to their APIs
13+
but don't need the complexity of ASP .NET Core's Authentication machinery, a simpler Auth Story would be preferred.
14+
15+
With the introduction of API Keys in this release we're able to provide a simpler Auth Story for .NET 8 Microservices
16+
that's easy for **Admin** Users to manage and control which trusted clients and B2B Integrations can access their functionality.
17+
18+
:::youtube 0ceU91ZBhTQ
19+
Simple Auth Story with API Keys ideal for .NET 8 Microservices
20+
:::
21+
22+
The easiest way to get started is by creating a new Empty project with API Keys enabled with your preferred database
23+
to store the API Keys in. SQLite is a good choice for stand-alone Apps as it doesn't require any infrastructure dependencies.
24+
25+
<div class="not-prose mx-auto">
26+
<h3 id="template" class="mb-4 text-4xl tracking-tight font-extrabold text-gray-900">
27+
Create a new Empty project with API Keys
28+
</h3>
29+
<auth-templates></auth-templates>
30+
</div>
31+
32+
### Existing Projects
33+
34+
Existing projects not configured with Authentication can enable this simple Auth configuration by running:
35+
36+
:::sh
37+
x mix apikeys-auth
38+
:::
39+
40+
Which will add the [ServiceStack.Server](https://nuget.org/packages/ServiceStack.Server) dependency and the
41+
[Modular Startup](/modular-startup) configuration below:
42+
43+
```csharp
44+
public class ConfigureApiKeys : IHostingStartup
45+
{
46+
public void Configure(IWebHostBuilder builder) => builder
47+
.ConfigureServices(services =>
48+
{
49+
services.AddPlugin(new AuthFeature(new AuthSecretAuthProvider("p@55wOrd")));
50+
services.AddPlugin(new ApiKeysFeature
51+
{
52+
// Optional: Available Scopes Admin Users can assign to any API Key
53+
// Features = [
54+
// "Paid",
55+
// "Tracking",
56+
// ],
57+
// Optional: Available Features Admin Users can assign to any API Key
58+
// Scopes = [
59+
// "todo:read",
60+
// "todo:write",
61+
// ],
62+
});
63+
})
64+
.ConfigureAppHost(appHost =>
65+
{
66+
using var db = appHost.Resolve<IDbConnectionFactory>().Open();
67+
var feature = appHost.GetPlugin<ApiKeysFeature>();
68+
feature.InitSchema(db);
69+
});
70+
}
71+
```
72+
73+
Which configures the **AuthSecretAuthProvider** with the **Admin** password and **ApiKeysFeature** to enable [API Keys](/auth/apikeys) support.
74+
75+
### Admin UI
76+
77+
The **Admin** password will give you access to the [Admin UI](/admin-ui) at:
78+
79+
:::{.text-4xl .text-center .text-indigo-800}
80+
/admin-ui
81+
:::
82+
83+
![](/img/pages/auth/simple/admin-ui-signin.png)
84+
85+
![](/img/pages/auth/simple/admin-ui-dashboard.png)
86+
87+
### API Keys Admin UI
88+
89+
Clicking on **API Keys** menu item will take you to the API Keys Admin UI where you'll be able to create new API Keys
90+
that you can distribute to different API consumers you want to be able to access your APIs:
91+
92+
![](/img/pages/auth/simple/admin-ui-apikeys.png)
93+
94+
The **ApiKeysFeature** plugin will let you control different parts of the UI, including what **Features** you want to
95+
assign to API Keys and what **Scopes** you want individual API Keys to be able to have access to.
96+
97+
```csharp
98+
services.AddPlugin(new ApiKeysFeature
99+
{
100+
Features = [
101+
"Paid",
102+
"Tracking",
103+
],
104+
Scopes = [
105+
"todo:read",
106+
"todo:write",
107+
],
108+
// ExpiresIn =[
109+
// new("", "Never"),
110+
// new("30", "30 days"),
111+
// new("365", "365 days"),
112+
// ],
113+
// Hide = ["RestrictTo","Notes"],
114+
});
115+
```
116+
117+
Any configuration on the plugin will be reflected in the UI:
118+
119+
![](/img/pages/auth/simple/admin-ui-apikeys-new.png)
120+
121+
The API Keys Admin UI also lets you view and manage all API Keys in your App, including the ability to revoke API Keys,
122+
extend their Expiration date as well as manage any Scopes and Features assigned to API Keys.
123+
124+
![](/img/pages/auth/simple/admin-ui-apikeys-edit.png)
125+
126+
### Protect APIs with API Keys
127+
128+
You'll now be able to protect APIs by annotating Request DTOs with the `[ValidateApiKey]` attribute:
129+
130+
```csharp
131+
[ValidateApiKey]
132+
public class Hello : IGet, IReturn<HelloResponse>
133+
{
134+
public required string Name { get; set; }
135+
}
136+
```
137+
138+
Which only allows requests with a **valid API Key** to access the Service.
139+
140+
### Scopes
141+
142+
We can further restrict API access by assigning them a scope which will only allow access to Valid API Keys configured
143+
with that scope, e.g:
144+
145+
```csharp
146+
[ValidateApiKey("todo:read")]
147+
public class QueryTodos : QueryDb<Todo>
148+
{
149+
public long? Id { get; set; }
150+
public List<long>? Ids { get; set; }
151+
public string? TextContains { get; set; }
152+
}
153+
154+
[ValidateApiKey("todo:write")]
155+
public class CreateTodo : ICreateDb<Todo>, IReturn<Todo>
156+
{
157+
[ValidateNotEmpty]
158+
public required string Text { get; set; }
159+
public bool IsFinished { get; set; }
160+
}
161+
162+
[ValidateApiKey("todo:write")]
163+
public class UpdateTodo : IUpdateDb<Todo>, IReturn<Todo>
164+
{
165+
public long Id { get; set; }
166+
[ValidateNotEmpty]
167+
public required string Text { get; set; }
168+
public bool IsFinished { get; set; }
169+
}
170+
171+
[ValidateApiKey("todo:write")]
172+
public class DeleteTodos : IDeleteDb<Todo>, IReturnVoid
173+
{
174+
public long? Id { get; set; }
175+
public List<long>? Ids { get; set; }
176+
}
177+
```
178+
179+
### Restrict To APIs
180+
181+
Scopes allow for coarse-grained access control allowing a single scope to access a logical group of APIs. For more
182+
fine-grained control you can use **Restrict To APIs** to specify just the APIs an API Key can access:
183+
184+
![](/img/pages/auth/simple/admin-ui-apikeys-restrict-to.png)
185+
186+
Unlike scopes which can access APIs with the **same scope** or **without a scope**, Valid API Keys configured with
187+
**Restrict To APIs** can only access those specific APIs.
188+
189+
### Features
190+
191+
Features are user-defined strings accessible within your Service implementation to provide different behavior
192+
based on Features assigned to the API Key, e.g:
193+
194+
```csharp
195+
public object Any(QueryTodos request)
196+
{
197+
if (Request.GetApiKey().HasFeature("Paid"))
198+
{
199+
//...
200+
}
201+
}
202+
```
203+
204+
### API Explorer
205+
206+
Support for API Keys is also integrated into the [API Explorer](/api-explorer) allowing
207+
users to use their API Keys to access API Key protected Services which are highlighted with a **Key** Icon:
208+
209+
![](/img/pages/auth/simple/apiexplorer-requires-apikey.png)
210+
211+
Users can enter their API Key by clicking on the **Key** Icon in the top right, or the link in the Warning alert
212+
when trying to access an API Key protected Service:
213+
214+
![](/img/pages/auth/simple/apiexplorer-apikey-dialog.png)
215+
216+
### Client Usage
217+
218+
All HTTP and existing [Service Clients](https://docs.servicestack.net/clients-overview) can be configured to use API Keys
219+
for machine-to-machine communication, which like most API Key implementations can be passed in a [HTTP Authorization Bearer Token](https://datatracker.ietf.org/doc/html/rfc6750#section-2.1)
220+
that can be configured in Service Clients with:
221+
222+
#### C#
223+
224+
```csharp
225+
var client = new JsonApiClient(BaseUrl) {
226+
BearerToken = apiKey
227+
};
228+
```
229+
230+
#### TypeScript
231+
232+
```ts
233+
const client = new JsonServiceClient(BaseUrl)
234+
client.bearerToken = apiKey
235+
```
236+
237+
### API Key HTTP Header
238+
239+
Alternatively, API Keys can also be passed in the `X-Api-Key` HTTP Header which allows clients to be configured
240+
with an alternative Bearer Token allowing the same client to call both **Authenticated** and **API Key** protected APIs, e.g:
241+
242+
#### C#
243+
244+
```csharp
245+
var client = new JsonApiClient(BaseUrl) {
246+
BearerToken = jwt,
247+
Headers = {
248+
[HttpHeaders.XApiKey] = apiKey
249+
}
250+
};
251+
```
252+
253+
#### TypeScript
254+
255+
```ts
256+
const client = new JsonServiceClient(BaseUrl)
257+
client.bearerToken = apiKey
258+
client.headers.set('X-Api-Key', apiKey)
259+
```
260+
261+
### Summary
262+
263+
We hope this shows how stand-alone .NET 8 Microservices and self-contained Docker Apps can use the
264+
simple **Admin** and **API Keys** configuration to easily secure their APIs, complete with **Management UI**
265+
and **typed Service Client** integrations.

0 commit comments

Comments
 (0)