You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
265 lines
11 KiB
265 lines
11 KiB
using System.Globalization;
|
|
using OpenIddict.Abstractions;
|
|
using OpenIddict.Sandbox.AspNetCore.Server.Models;
|
|
using static OpenIddict.Abstractions.OpenIddictConstants;
|
|
|
|
namespace OpenIddict.Sandbox.AspNetCore.Server;
|
|
|
|
public class Worker : IHostedService
|
|
{
|
|
private readonly IServiceProvider _serviceProvider;
|
|
|
|
public Worker(IServiceProvider serviceProvider)
|
|
=> _serviceProvider = serviceProvider;
|
|
|
|
public async Task StartAsync(CancellationToken cancellationToken)
|
|
{
|
|
await using var scope = _serviceProvider.CreateAsyncScope();
|
|
|
|
var context = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
|
|
await context.Database.EnsureCreatedAsync(cancellationToken);
|
|
|
|
await RegisterApplicationsAsync(scope.ServiceProvider);
|
|
await RegisterScopesAsync(scope.ServiceProvider);
|
|
|
|
static async Task RegisterApplicationsAsync(IServiceProvider provider)
|
|
{
|
|
var manager = provider.GetRequiredService<IOpenIddictApplicationManager>();
|
|
|
|
if (await manager.FindByClientIdAsync("console") is null)
|
|
{
|
|
await manager.CreateAsync(new OpenIddictApplicationDescriptor
|
|
{
|
|
// Note: the application must be registered as a native application to force OpenIddict
|
|
// to apply a relaxed redirect_uri validation policy that allows specifying a random port.
|
|
ApplicationType = ApplicationTypes.Native,
|
|
ClientId = "console",
|
|
ConsentType = ConsentTypes.Systematic,
|
|
DisplayName = "Console client application",
|
|
DisplayNames =
|
|
{
|
|
[CultureInfo.GetCultureInfo("fr-FR")] = "Application cliente console"
|
|
},
|
|
RedirectUris =
|
|
{
|
|
// Note: the port must not be explicitly specified as it is selected
|
|
// dynamically at runtime by the OpenIddict client system integration.
|
|
new Uri("http://localhost/callback/login/local")
|
|
},
|
|
Permissions =
|
|
{
|
|
Permissions.Endpoints.Authorization,
|
|
Permissions.Endpoints.Device,
|
|
Permissions.Endpoints.Token,
|
|
Permissions.GrantTypes.AuthorizationCode,
|
|
Permissions.GrantTypes.DeviceCode,
|
|
Permissions.GrantTypes.RefreshToken,
|
|
Permissions.ResponseTypes.Code,
|
|
Permissions.Scopes.Email,
|
|
Permissions.Scopes.Profile,
|
|
Permissions.Scopes.Roles,
|
|
Permissions.Prefixes.Scope + "demo_api"
|
|
},
|
|
Requirements =
|
|
{
|
|
Requirements.Features.ProofKeyForCodeExchange
|
|
}
|
|
});
|
|
}
|
|
|
|
if (await manager.FindByClientIdAsync("mvc") is null)
|
|
{
|
|
await manager.CreateAsync(new OpenIddictApplicationDescriptor
|
|
{
|
|
ApplicationType = ApplicationTypes.Web,
|
|
ClientId = "mvc",
|
|
ClientSecret = "901564A5-E7FE-42CB-B10D-61EF6A8F3654",
|
|
ConsentType = ConsentTypes.Explicit,
|
|
DisplayName = "MVC client application",
|
|
DisplayNames =
|
|
{
|
|
[CultureInfo.GetCultureInfo("fr-FR")] = "Application cliente MVC"
|
|
},
|
|
RedirectUris =
|
|
{
|
|
new Uri("https://localhost:44381/callback/login/local")
|
|
},
|
|
PostLogoutRedirectUris =
|
|
{
|
|
new Uri("https://localhost:44381/callback/logout/local")
|
|
},
|
|
Permissions =
|
|
{
|
|
Permissions.Endpoints.Authorization,
|
|
Permissions.Endpoints.Logout,
|
|
Permissions.Endpoints.Token,
|
|
Permissions.GrantTypes.AuthorizationCode,
|
|
Permissions.GrantTypes.RefreshToken,
|
|
Permissions.ResponseTypes.Code,
|
|
Permissions.Scopes.Email,
|
|
Permissions.Scopes.Profile,
|
|
Permissions.Scopes.Roles,
|
|
Permissions.Prefixes.Scope + "demo_api"
|
|
},
|
|
Requirements =
|
|
{
|
|
Requirements.Features.ProofKeyForCodeExchange
|
|
}
|
|
});
|
|
}
|
|
|
|
if (await manager.FindByClientIdAsync("winforms") is null)
|
|
{
|
|
await manager.CreateAsync(new OpenIddictApplicationDescriptor
|
|
{
|
|
ApplicationType = ApplicationTypes.Native,
|
|
ClientId = "winforms",
|
|
ConsentType = ConsentTypes.Systematic,
|
|
DisplayName = "WinForms client application",
|
|
DisplayNames =
|
|
{
|
|
[CultureInfo.GetCultureInfo("fr-FR")] = "Application cliente WinForms"
|
|
},
|
|
RedirectUris =
|
|
{
|
|
new Uri("com.openiddict.sandbox.winforms.client:/callback/login/local")
|
|
},
|
|
Permissions =
|
|
{
|
|
Permissions.Endpoints.Authorization,
|
|
Permissions.Endpoints.Token,
|
|
Permissions.GrantTypes.AuthorizationCode,
|
|
Permissions.GrantTypes.RefreshToken,
|
|
Permissions.ResponseTypes.Code,
|
|
Permissions.Scopes.Email,
|
|
Permissions.Scopes.Profile,
|
|
Permissions.Scopes.Roles,
|
|
Permissions.Prefixes.Scope + "demo_api"
|
|
},
|
|
Requirements =
|
|
{
|
|
Requirements.Features.ProofKeyForCodeExchange
|
|
}
|
|
});
|
|
}
|
|
|
|
if (await manager.FindByClientIdAsync("wpf") is null)
|
|
{
|
|
await manager.CreateAsync(new OpenIddictApplicationDescriptor
|
|
{
|
|
ApplicationType = ApplicationTypes.Native,
|
|
ClientId = "wpf",
|
|
ConsentType = ConsentTypes.Systematic,
|
|
DisplayName = "WPF client application",
|
|
DisplayNames =
|
|
{
|
|
[CultureInfo.GetCultureInfo("fr-FR")] = "Application cliente WPF"
|
|
},
|
|
RedirectUris =
|
|
{
|
|
new Uri("com.openiddict.sandbox.wpf.client:/callback/login/local")
|
|
},
|
|
Permissions =
|
|
{
|
|
Permissions.Endpoints.Authorization,
|
|
Permissions.Endpoints.Token,
|
|
Permissions.GrantTypes.AuthorizationCode,
|
|
Permissions.GrantTypes.RefreshToken,
|
|
Permissions.ResponseTypes.Code,
|
|
Permissions.Scopes.Email,
|
|
Permissions.Scopes.Profile,
|
|
Permissions.Scopes.Roles,
|
|
Permissions.Prefixes.Scope + "demo_api"
|
|
},
|
|
Requirements =
|
|
{
|
|
Requirements.Features.ProofKeyForCodeExchange
|
|
}
|
|
});
|
|
}
|
|
|
|
// Note: when using introspection instead of local token validation,
|
|
// an application entry MUST be created to allow the resource server
|
|
// to communicate with OpenIddict's introspection endpoint.
|
|
if (await manager.FindByClientIdAsync("resource_server") is null)
|
|
{
|
|
await manager.CreateAsync(new OpenIddictApplicationDescriptor
|
|
{
|
|
ClientId = "resource_server",
|
|
ClientSecret = "80B552BB-4CD8-48DA-946E-0815E0147DD2",
|
|
Permissions =
|
|
{
|
|
Permissions.Endpoints.Introspection
|
|
}
|
|
});
|
|
}
|
|
|
|
// To test this sample with Postman, use the following settings:
|
|
//
|
|
// * Authorization URL: https://localhost:44395/connect/authorize
|
|
// * Access token URL: https://localhost:44395/connect/token
|
|
// * Client ID: postman
|
|
// * Client secret: [blank] (not used with public clients)
|
|
// * Scope: openid email profile roles
|
|
// * Grant type: authorization code
|
|
// * Request access token locally: yes
|
|
if (await manager.FindByClientIdAsync("postman") is null)
|
|
{
|
|
await manager.CreateAsync(new OpenIddictApplicationDescriptor
|
|
{
|
|
ApplicationType = ApplicationTypes.Native,
|
|
ClientId = "postman",
|
|
ConsentType = ConsentTypes.Systematic,
|
|
DisplayName = "Postman",
|
|
RedirectUris =
|
|
{
|
|
new Uri("https://oauth.pstmn.io/v1/callback")
|
|
},
|
|
Permissions =
|
|
{
|
|
Permissions.Endpoints.Authorization,
|
|
Permissions.Endpoints.Device,
|
|
Permissions.Endpoints.Token,
|
|
Permissions.GrantTypes.AuthorizationCode,
|
|
Permissions.GrantTypes.DeviceCode,
|
|
Permissions.GrantTypes.Password,
|
|
Permissions.GrantTypes.RefreshToken,
|
|
Permissions.ResponseTypes.Code,
|
|
Permissions.Scopes.Email,
|
|
Permissions.Scopes.Profile,
|
|
Permissions.Scopes.Roles
|
|
},
|
|
Settings =
|
|
{
|
|
// Use a shorter access token lifetime for tokens issued to the Postman application.
|
|
[Settings.TokenLifetimes.AccessToken] = TimeSpan.FromMinutes(10).ToString("c", CultureInfo.InvariantCulture)
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
static async Task RegisterScopesAsync(IServiceProvider provider)
|
|
{
|
|
var manager = provider.GetRequiredService<IOpenIddictScopeManager>();
|
|
|
|
if (await manager.FindByNameAsync("demo_api") is null)
|
|
{
|
|
await manager.CreateAsync(new OpenIddictScopeDescriptor
|
|
{
|
|
DisplayName = "Demo API access",
|
|
DisplayNames =
|
|
{
|
|
[CultureInfo.GetCultureInfo("fr-FR")] = "Accès à l'API de démo"
|
|
},
|
|
Name = "demo_api",
|
|
Resources =
|
|
{
|
|
"resource_server"
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
|
|
}
|
|
|