-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
b52d808
commit 540def1
Showing
12 changed files
with
253 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
16 changes: 16 additions & 0 deletions
16
examples/Passwordless.MultiTenancy.Example/Controllers/MultiTenancyController.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
using Microsoft.AspNetCore.Mvc; | ||
|
||
namespace Passwordless.MultiTenancy.Example.Controllers; | ||
|
||
[ApiController] | ||
[Route("[controller]")] | ||
public class MultiTenancyController : ControllerBase | ||
{ | ||
[HttpGet("Users")] | ||
public async Task<IActionResult> Get([FromServices] IPasswordlessClient client) | ||
{ | ||
var users = await client.ListUsersAsync(); | ||
|
||
return Ok(users); | ||
} | ||
} |
17 changes: 17 additions & 0 deletions
17
examples/Passwordless.MultiTenancy.Example/Passwordless.MultiTenancy.Example.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<Project Sdk="Microsoft.NET.Sdk.Web"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net8.0</TargetFramework> | ||
<Nullable>enable</Nullable> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0"/> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\..\src\Passwordless\Passwordless.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |
10 changes: 10 additions & 0 deletions
10
examples/Passwordless.MultiTenancy.Example/Passwordless/IPasswordlessClientBuilder.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
namespace Passwordless.MultiTenancy.Example.Passwordless; | ||
|
||
public interface IPasswordlessClientBuilder | ||
{ | ||
PasswordlessClientBuilder WithApiUrl(string apiUrl); | ||
|
||
PasswordlessClientBuilder WithTenant(string tenant); | ||
|
||
PasswordlessClient Build(); | ||
} |
35 changes: 35 additions & 0 deletions
35
examples/Passwordless.MultiTenancy.Example/Passwordless/PasswordlessClientBuilder.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
using Microsoft.Extensions.Options; | ||
|
||
namespace Passwordless.MultiTenancy.Example.Passwordless; | ||
|
||
public class PasswordlessClientBuilder : IPasswordlessClientBuilder | ||
{ | ||
private readonly PasswordlessOptions _options = new() | ||
{ | ||
ApiSecret = null! | ||
}; | ||
private readonly PasswordlessMultiTenancyConfiguration _multiTenancyOptions; | ||
|
||
public PasswordlessClientBuilder(IOptions<PasswordlessMultiTenancyConfiguration> multiTenancyOptions) | ||
{ | ||
_multiTenancyOptions = multiTenancyOptions.Value ?? throw new ArgumentNullException(nameof(multiTenancyOptions)); | ||
} | ||
|
||
public PasswordlessClientBuilder WithApiUrl(string apiUrl) | ||
{ | ||
_options.ApiUrl = apiUrl; | ||
return this; | ||
} | ||
|
||
public PasswordlessClientBuilder WithTenant(string tenant) | ||
{ | ||
var tenantConfiguration = _multiTenancyOptions.Tenants[tenant]; | ||
_options.ApiSecret = tenantConfiguration.ApiSecret; | ||
return this; | ||
} | ||
|
||
public PasswordlessClient Build() | ||
{ | ||
return new PasswordlessClient(_options); | ||
} | ||
} |
6 changes: 6 additions & 0 deletions
6
...s/Passwordless.MultiTenancy.Example/Passwordless/PasswordlessMultiTenancyConfiguration.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
namespace Passwordless.MultiTenancy.Example.Passwordless; | ||
|
||
public class PasswordlessMultiTenancyConfiguration | ||
{ | ||
public Dictionary<string, TenantConfiguration> Tenants { get; set; } = new(); | ||
} |
6 changes: 6 additions & 0 deletions
6
examples/Passwordless.MultiTenancy.Example/Passwordless/TenantConfiguration.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
namespace Passwordless.MultiTenancy.Example.Passwordless; | ||
|
||
public class TenantConfiguration | ||
{ | ||
public required string ApiSecret { get; set; } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
using Passwordless; | ||
using Passwordless.MultiTenancy.Example.Passwordless; | ||
|
||
var builder = WebApplication.CreateBuilder(args); | ||
|
||
// Add services to the container. | ||
|
||
builder.Services.AddControllers(); | ||
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle | ||
builder.Services.AddEndpointsApiExplorer(); | ||
builder.Services.AddSwaggerGen(); | ||
|
||
// Multi-tenancy: For accessing the current HTTP context | ||
builder.Services.AddHttpContextAccessor(); | ||
|
||
// Multi-tenancy: To build the PasswordlessClient | ||
builder.Services.AddSingleton<IPasswordlessClientBuilder, PasswordlessClientBuilder>(); | ||
|
||
// Multi-tenancy: To get the multi-tenant api secrets from our configuration | ||
builder.Services.AddOptions<PasswordlessMultiTenancyConfiguration>().BindConfiguration("Passwordless"); | ||
|
||
// Multi-tenancy: Integrate the multi-tenant PasswordlessClient with the HttpClient | ||
builder.Services.AddHttpClient<IPasswordlessClient, PasswordlessClient>((http, sp) => | ||
{ | ||
|
||
var httpContextAccessor = sp.GetRequiredService<IHttpContextAccessor>(); | ||
var host = httpContextAccessor.HttpContext!.Request.Host; | ||
|
||
// gameofthrones or thewalkingdead tenant | ||
var tenant = host.Host.Split('.')[0]; | ||
|
||
var clientBuilder = sp.GetRequiredService<IPasswordlessClientBuilder>(); | ||
clientBuilder.WithTenant(tenant); | ||
|
||
var passwordlessClient = clientBuilder.Build(); | ||
return passwordlessClient; | ||
}); | ||
|
||
builder.Services.AddScoped(sp => (PasswordlessClient)sp.GetRequiredService<IPasswordlessClient>()); | ||
|
||
|
||
var app = builder.Build(); | ||
|
||
// Configure the HTTP request pipeline. | ||
if (app.Environment.IsDevelopment()) | ||
{ | ||
app.UseSwagger(); | ||
app.UseSwaggerUI(); | ||
} | ||
|
||
app.UseAuthorization(); | ||
|
||
app.MapControllers(); | ||
|
||
app.Run(); |
31 changes: 31 additions & 0 deletions
31
examples/Passwordless.MultiTenancy.Example/Properties/launchSettings.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
{ | ||
"$schema": "http://json.schemastore.org/launchsettings.json", | ||
"iisSettings": { | ||
"windowsAuthentication": false, | ||
"anonymousAuthentication": true, | ||
"iisExpress": { | ||
"applicationUrl": "http://localhost:62502", | ||
"sslPort": 0 | ||
} | ||
}, | ||
"profiles": { | ||
"http": { | ||
"commandName": "Project", | ||
"dotnetRunMessages": true, | ||
"launchBrowser": true, | ||
"launchUrl": "swagger", | ||
"applicationUrl": "http://localhost:5265", | ||
"environmentVariables": { | ||
"ASPNETCORE_ENVIRONMENT": "Development" | ||
} | ||
}, | ||
"IIS Express": { | ||
"commandName": "IISExpress", | ||
"launchBrowser": true, | ||
"launchUrl": "swagger", | ||
"environmentVariables": { | ||
"ASPNETCORE_ENVIRONMENT": "Development" | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
# Requirements: | ||
- .NET 8.0 or later | ||
- Passwordless.dev Pro or Enterprise | ||
|
||
# Getting started | ||
This example demonstrates how to use the Passwordless library in a multi-tenant environment. Where the subdomain is used | ||
to identify the tenant. For example: | ||
|
||
- `gameofthrones.passwordless.local` | ||
- `thewalkingdead.passwordless.local` | ||
|
||
We can achieve this by bootstrapping the Passwordless SDK ourselves in `Program.cs` and providing the necessary | ||
configuration. | ||
|
||
For a tenant `thewalkingdead` or `gameofthrones` respectively. You would find the configuration then in your appsettings.json | ||
file. Similarly, you can use a database or any other configuration source. | ||
|
||
```json | ||
{ | ||
"Passwordless": { | ||
"Tenants": { | ||
"gameofthrones": { | ||
"ApiSecret": "gameofthrones:secret:00000000000000000000000000000000" | ||
}, | ||
"thewalkingdead": { | ||
"ApiSecret": "thewalkingdead:secret:00000000000000000000000000000000" | ||
} | ||
} | ||
} | ||
} | ||
``` | ||
|
||
1. Create entries in the hosts file: | ||
|
||
127.0.0.1 gameofthrones.passwordless.local | ||
127.0.0.1 thewalkingdead.passwordless.local | ||
|
||
These are the tenants of your own backend as an example named 'gameofthrones' and 'thewalkingdead' | ||
|
||
2. Modify any tenants and their related `ApiSecret` setting in the `appsettings.json` file. | ||
|
||
3. Run the sample locally with .NET 8, debug if you have to step through. And visit: | ||
|
||
- http://gameofthrones.passwordless.local/swagger/index.html | ||
- http://thewalkingdead.passwordless.local/swagger/index.html | ||
|
||
4. Call the 'Users' endpoint from Swagger to test using your own API secrets obtained. | ||
|
||
You can refer to the `Passwordless.Example` project how to create your own complete backend with the Passwordless | ||
library, as this example is a stripped-down version of it to demonstrate multi-tenancy in a simple way. |
19 changes: 19 additions & 0 deletions
19
examples/Passwordless.MultiTenancy.Example/appsettings.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
{ | ||
"Logging": { | ||
"LogLevel": { | ||
"Default": "Information", | ||
"Microsoft.AspNetCore": "Warning" | ||
} | ||
}, | ||
"AllowedHosts": "*", | ||
"Passwordless": { | ||
"Tenants": { | ||
"gameofthrones": { | ||
"ApiSecret": "app1:secret:a06f1e0e1b3149a385f7fc50553d21f8" | ||
}, | ||
"thewalkingdead": { | ||
"ApiSecret": "app2:secret:a06f1e0e1b3149a385f7fc50553d21f8" | ||
} | ||
} | ||
} | ||
} |