├── .editorconfig ├── .gitattributes ├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE │ ├── bug_report.yml │ └── config.yml ├── PULL_REQUEST_TEMPLATE.md ├── workflow-gen │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ └── workflow-gen.csproj └── workflows │ ├── access-token-management-ci.yml │ ├── access-token-management-release.yml │ ├── codeql.yml │ ├── generate-test-reports.yml │ ├── identity-model-ci.yml │ ├── identity-model-oidc-client-ci.yml │ ├── identity-model-oidc-client-release.yml │ ├── identity-model-release.yml │ ├── ignore-this-ci.yml │ ├── ignore-this-release.yml │ └── scorecard.yml ├── .gitignore ├── .vscode ├── launch.json └── tasks.json ├── Directory.Packages.props ├── LICENSE ├── README.md ├── access-token-management ├── .config │ └── dotnet-tools.json ├── README.md ├── perf │ ├── .gitignore │ ├── Perf.DevServer.ServiceDefaults │ │ ├── Extensions.cs │ │ └── Perf.DevServer.ServiceDefaults.csproj │ ├── Perf.DevServer │ │ ├── Perf.DevServer.csproj │ │ ├── Perf.DevServer.v3.ncrunchproject │ │ ├── Program.cs │ │ ├── Properties │ │ │ └── launchSettings.json │ │ ├── appsettings.Development.json │ │ └── appsettings.json │ ├── Perf.IdentityServer │ │ ├── Config.cs │ │ ├── HostingExtensions.cs │ │ ├── Perf.IdentityServer.csproj │ │ ├── Program.cs │ │ ├── Properties │ │ │ └── launchSettings.json │ │ └── appsettings.json │ ├── Perf.K6 │ │ ├── package-lock.json │ │ ├── package.json │ │ └── token.ts │ └── Perf.TokenEndpoint │ │ ├── Perf.TokenEndpoint.csproj │ │ ├── Program.cs │ │ ├── Properties │ │ └── launchSettings.json │ │ ├── TokenEndpoint.http │ │ ├── appsettings.Development.json │ │ └── appsettings.json ├── samples │ ├── BlazorServer │ │ ├── App.razor │ │ ├── BlazorServer.csproj │ │ ├── BlazorServer.v3.ncrunchproject │ │ ├── Data │ │ │ └── WeatherForecast.cs │ │ ├── HostingExtensions.cs │ │ ├── Pages │ │ │ ├── Counter.razor │ │ │ ├── Error.cshtml │ │ │ ├── Error.cshtml.cs │ │ │ ├── FetchData.razor │ │ │ ├── FetchRemoteData.razor │ │ │ └── Index.razor │ │ ├── Plumbing │ │ │ ├── AccountController.cs │ │ │ ├── CookieEvents.cs │ │ │ ├── OidcEvents.cs │ │ │ └── ServerSideTokenStore.cs │ │ ├── Program.cs │ │ ├── Properties │ │ │ └── launchSettings.json │ │ ├── Routes.razor │ │ ├── Services │ │ │ ├── RemoteApiService.cs │ │ │ └── WeatherForecastService.cs │ │ ├── Shared │ │ │ ├── LoginDisplay.razor │ │ │ ├── MainLayout.razor │ │ │ ├── MainLayout.razor.css │ │ │ ├── NavMenu.razor │ │ │ ├── NavMenu.razor.css │ │ │ ├── RedirectToLogin.razor │ │ │ └── SurveyPrompt.razor │ │ ├── _Imports.razor │ │ └── wwwroot │ │ │ ├── css │ │ │ ├── bootstrap │ │ │ │ ├── bootstrap.min.css │ │ │ │ └── bootstrap.min.css.map │ │ │ ├── open-iconic │ │ │ │ ├── FONT-LICENSE │ │ │ │ ├── ICON-LICENSE │ │ │ │ ├── README.md │ │ │ │ └── font │ │ │ │ │ ├── css │ │ │ │ │ └── open-iconic-bootstrap.min.css │ │ │ │ │ └── fonts │ │ │ │ │ ├── open-iconic.eot │ │ │ │ │ ├── open-iconic.otf │ │ │ │ │ ├── open-iconic.svg │ │ │ │ │ ├── open-iconic.ttf │ │ │ │ │ └── open-iconic.woff │ │ │ └── site.css │ │ │ └── favicon.ico │ ├── Directory.Build.props │ ├── Web │ │ ├── Controllers │ │ │ └── HomeController.cs │ │ ├── Program.cs │ │ ├── Properties │ │ │ └── launchSettings.json │ │ ├── Startup.cs │ │ ├── TypedClient.cs │ │ ├── Views │ │ │ ├── Home │ │ │ │ ├── CallApi.cshtml │ │ │ │ ├── Index.cshtml │ │ │ │ └── Secure.cshtml │ │ │ ├── Shared │ │ │ │ ├── _Layout.cshtml │ │ │ │ └── _ValidationScriptsPartial.cshtml │ │ │ ├── _ViewImports.cshtml │ │ │ └── _ViewStart.cshtml │ │ ├── Web.csproj │ │ ├── Web.v3.ncrunchproject │ │ ├── appsettings.json │ │ └── wwwroot │ │ │ ├── css │ │ │ └── site.css │ │ │ ├── favicon.ico │ │ │ ├── js │ │ │ └── site.js │ │ │ └── lib │ │ │ ├── bootstrap │ │ │ ├── LICENSE │ │ │ └── dist │ │ │ │ ├── css │ │ │ │ ├── bootstrap-grid.css │ │ │ │ ├── bootstrap-grid.css.map │ │ │ │ ├── bootstrap-grid.min.css │ │ │ │ ├── bootstrap-grid.min.css.map │ │ │ │ ├── bootstrap-reboot.css │ │ │ │ ├── bootstrap-reboot.css.map │ │ │ │ ├── bootstrap-reboot.min.css │ │ │ │ ├── bootstrap-reboot.min.css.map │ │ │ │ ├── bootstrap.css │ │ │ │ ├── bootstrap.css.map │ │ │ │ ├── bootstrap.min.css │ │ │ │ └── bootstrap.min.css.map │ │ │ │ └── js │ │ │ │ ├── bootstrap.bundle.js │ │ │ │ ├── bootstrap.bundle.js.map │ │ │ │ ├── bootstrap.bundle.min.js │ │ │ │ ├── bootstrap.bundle.min.js.map │ │ │ │ ├── bootstrap.js │ │ │ │ ├── bootstrap.js.map │ │ │ │ ├── bootstrap.min.js │ │ │ │ └── bootstrap.min.js.map │ │ │ ├── jquery-validation-unobtrusive │ │ │ ├── LICENSE.txt │ │ │ ├── jquery.validate.unobtrusive.js │ │ │ └── jquery.validate.unobtrusive.min.js │ │ │ ├── jquery-validation │ │ │ ├── LICENSE.md │ │ │ └── dist │ │ │ │ ├── additional-methods.js │ │ │ │ ├── additional-methods.min.js │ │ │ │ ├── jquery.validate.js │ │ │ │ └── jquery.validate.min.js │ │ │ └── jquery │ │ │ ├── LICENSE.txt │ │ │ └── dist │ │ │ ├── jquery.js │ │ │ ├── jquery.min.js │ │ │ └── jquery.min.map │ ├── WebJarJwt │ │ ├── ClientAssertionService.cs │ │ ├── Controllers │ │ │ └── HomeController.cs │ │ ├── OidcEvents.cs │ │ ├── Program.cs │ │ ├── Properties │ │ │ └── launchSettings.json │ │ ├── Startup.cs │ │ ├── TypedClient.cs │ │ ├── Views │ │ │ ├── Home │ │ │ │ ├── CallApi.cshtml │ │ │ │ ├── Index.cshtml │ │ │ │ └── Secure.cshtml │ │ │ ├── Shared │ │ │ │ ├── _Layout.cshtml │ │ │ │ └── _ValidationScriptsPartial.cshtml │ │ │ ├── _ViewImports.cshtml │ │ │ └── _ViewStart.cshtml │ │ ├── WebJarJwt.csproj │ │ ├── WebJarJwt.v3.ncrunchproject │ │ └── wwwroot │ │ │ ├── css │ │ │ └── site.css │ │ │ ├── favicon.ico │ │ │ ├── js │ │ │ └── site.js │ │ │ └── lib │ │ │ ├── bootstrap │ │ │ ├── LICENSE │ │ │ └── dist │ │ │ │ ├── css │ │ │ │ ├── bootstrap-grid.css │ │ │ │ ├── bootstrap-grid.css.map │ │ │ │ ├── bootstrap-grid.min.css │ │ │ │ ├── bootstrap-grid.min.css.map │ │ │ │ ├── bootstrap-reboot.css │ │ │ │ ├── bootstrap-reboot.css.map │ │ │ │ ├── bootstrap-reboot.min.css │ │ │ │ ├── bootstrap-reboot.min.css.map │ │ │ │ ├── bootstrap.css │ │ │ │ ├── bootstrap.css.map │ │ │ │ ├── bootstrap.min.css │ │ │ │ └── bootstrap.min.css.map │ │ │ │ └── js │ │ │ │ ├── bootstrap.bundle.js │ │ │ │ ├── bootstrap.bundle.js.map │ │ │ │ ├── bootstrap.bundle.min.js │ │ │ │ ├── bootstrap.bundle.min.js.map │ │ │ │ ├── bootstrap.js │ │ │ │ ├── bootstrap.js.map │ │ │ │ ├── bootstrap.min.js │ │ │ │ └── bootstrap.min.js.map │ │ │ ├── jquery-validation-unobtrusive │ │ │ ├── LICENSE.txt │ │ │ ├── jquery.validate.unobtrusive.js │ │ │ └── jquery.validate.unobtrusive.min.js │ │ │ ├── jquery-validation │ │ │ ├── LICENSE.md │ │ │ └── dist │ │ │ │ ├── additional-methods.js │ │ │ │ ├── additional-methods.min.js │ │ │ │ ├── jquery.validate.js │ │ │ │ └── jquery.validate.min.js │ │ │ └── jquery │ │ │ ├── LICENSE.txt │ │ │ └── dist │ │ │ ├── jquery.js │ │ │ ├── jquery.min.js │ │ │ └── jquery.min.map │ ├── Worker │ │ ├── ClientAssertionService.cs │ │ ├── Program.cs │ │ ├── TypedClient.cs │ │ ├── Worker.csproj │ │ ├── Worker.v3.ncrunchproject │ │ ├── WorkerDPoPHttpClient.cs │ │ ├── WorkerHttpClient.cs │ │ ├── WorkerManual.cs │ │ ├── WorkerManualJwt.cs │ │ └── WorkerTypedHttpClient.cs │ └── WorkerDI │ │ ├── ClientAssertionService.cs │ │ ├── ClientCredentialsClientConfigureOptions.cs │ │ ├── Program.cs │ │ ├── TypedClient.cs │ │ ├── WorkerDI.csproj │ │ ├── WorkerDI.v3.ncrunchproject │ │ ├── WorkerHttpClient.cs │ │ ├── WorkerManual.cs │ │ ├── WorkerManualJwt.cs │ │ └── WorkerTypedHttpClient.cs ├── src │ ├── AccessTokenManagement.OpenIdConnect │ │ ├── AccessTokenManagement.OpenIdConnect.csproj │ │ ├── AccessTokenManagement.OpenIdConnect.v3.ncrunchproject │ │ ├── GlobalAliasses.cs │ │ ├── HttpContextExtensions.cs │ │ ├── IOpenIdConnectConfigurationService.cs │ │ ├── IOpenIdConnectUserTokenEndpoint.cs │ │ ├── IPrincipalAccessor.cs │ │ ├── IStoreTokensInAuthenticationProperties.cs │ │ ├── IUserTokenManager.cs │ │ ├── IUserTokenRequestConcurrencyControl.cs │ │ ├── IUserTokenStore.cs │ │ ├── Internal │ │ │ ├── AuthenticateResultCache.cs │ │ │ ├── AuthenticationSessionUserAccessTokenStore.cs │ │ │ ├── AuthorizationServerDPoPHandler.cs │ │ │ ├── BlazorServerUserAccessor.cs │ │ │ ├── CircuitServicesAccessor.cs │ │ │ ├── CircuitServicesServiceCollectionExtensions.cs │ │ │ ├── ConfigureOpenIdConnectClientCredentialsOptions.cs │ │ │ ├── ConfigureOpenIdConnectOptions.cs │ │ │ ├── HttpContextUserAccessor.cs │ │ │ ├── OpenIdConnectClientAccessTokenRetriever.cs │ │ │ ├── OpenIdConnectConfigurationService.cs │ │ │ ├── OpenIdConnectUserAccessTokenRetriever.cs │ │ │ ├── OpenIdConnectUserTokenEndpoint.cs │ │ │ ├── ServicesAccessorCircuitHandler.cs │ │ │ ├── StoreTokensInAuthenticationProperties.cs │ │ │ ├── TokenNames.cs │ │ │ ├── UserAccessTokenManagementService.cs │ │ │ └── UserTokenRequestConcurrencyControl.cs │ │ ├── OpenIdConnectClientConfiguration.cs │ │ ├── OpenIdConnectTokenManagementDefaults.cs │ │ ├── README.md │ │ ├── ServiceCollectionExtensions.cs │ │ ├── StringExtensions.cs │ │ ├── TokenForParameters.cs │ │ ├── TransformPrincipalAfterRefreshAsync.cs │ │ ├── UserRefreshToken.cs │ │ ├── UserToken.cs │ │ ├── UserTokenManagementOptions.cs │ │ └── UserTokenRequestParameters.cs │ ├── AccessTokenManagement │ │ ├── AccessToken.cs │ │ ├── AccessTokenManagement.csproj │ │ ├── AccessTokenManagement.v3.ncrunchproject │ │ ├── AccessTokenRequestHandler.cs │ │ ├── AccessTokenType.cs │ │ ├── ClientCredentialsCacheKey.cs │ │ ├── ClientCredentialsClient.cs │ │ ├── ClientCredentialsClientName.cs │ │ ├── ClientCredentialsToken.cs │ │ ├── ClientCredentialsTokenManagementBuilder.cs │ │ ├── ClientCredentialsTokenManagementDefaults.cs │ │ ├── ClientCredentialsTokenManagementOptions.cs │ │ ├── ClientId.cs │ │ ├── ClientSecret.cs │ │ ├── DPoP │ │ │ ├── DPoPExtensions.cs │ │ │ ├── DPoPNonce.cs │ │ │ ├── DPoPNonceContext.cs │ │ │ ├── DPoPProof.cs │ │ │ ├── DPoPProofKey.cs │ │ │ ├── DPoPProofRequest.cs │ │ │ ├── DPoPProofThumbPrint.cs │ │ │ ├── IDPoPKeyStore.cs │ │ │ ├── IDPoPNonceStore.cs │ │ │ ├── IDPoPNonceStoreKeyGenerator.cs │ │ │ ├── IDPoPProofService.cs │ │ │ └── Internal │ │ │ │ ├── DPoPErrors.cs │ │ │ │ ├── DPoPNonceStoreKeyGenerator.cs │ │ │ │ ├── DefaultDPoPKeyStore.cs │ │ │ │ ├── DefaultDPoPProofService.cs │ │ │ │ └── HybridDPoPNonceStore.cs │ │ ├── FailedResult.cs │ │ ├── ForceTokenRenewal.cs │ │ ├── GlobalAliasses.cs │ │ ├── IClientAssertionService.cs │ │ ├── IClientCredentialsCacheKeyGenerator.cs │ │ ├── IClientCredentialsTokenEndpoint.cs │ │ ├── IClientCredentialsTokenManager.cs │ │ ├── IdentityToken.cs │ │ ├── Internal │ │ │ ├── ClientCredentialsTokenClient.cs │ │ │ ├── ClientCredentialsTokenManager.cs │ │ │ ├── ClientCredentialsTokenRetriever.cs │ │ │ ├── Crypto.cs │ │ │ ├── DefaultClientCredentialsCacheKeyGenerator.cs │ │ │ ├── DuendeAccessTokenSerializationContext.cs │ │ │ ├── HybridCacheExtensions.cs │ │ │ ├── IStronglyTypedValue.cs │ │ │ ├── NoOpClientAssertionService.cs │ │ │ ├── RequestExtensions.cs │ │ │ ├── Resiliency.cs │ │ │ ├── StringParsers.cs │ │ │ ├── StringValueConverter.cs │ │ │ ├── StringValueJsonConverter.cs │ │ │ ├── ValidationRule.cs │ │ │ └── ValidationRules.cs │ │ ├── OTel │ │ │ ├── AccessTokenManagementMetrics.cs │ │ │ ├── ActivitySources.cs │ │ │ ├── Log.cs │ │ │ └── OTelParameters.cs │ │ ├── README.md │ │ ├── RefreshToken.cs │ │ ├── Resource.cs │ │ ├── Scheme.cs │ │ ├── Scope.cs │ │ ├── ServiceCollectionExtensions.cs │ │ ├── ServiceProviderKeys.cs │ │ ├── TokenRequestParameters.cs │ │ ├── TokenResult.cs │ │ └── TokenResultExtensions.cs │ └── Directory.Build.props └── test │ ├── AccessTokenManagement.Tests │ ├── AccessTokenHandler │ │ ├── AccessTokenHandlerTests.cs │ │ ├── Fixtures │ │ │ ├── AccessTokenHandlingBaseFixture.cs │ │ │ ├── ClientCredentialsFixture.cs │ │ │ ├── OidcClientFixture.cs │ │ │ └── OidcUserFixture.cs │ │ └── Helpers │ │ │ ├── ApiHttpMessageHandler.cs │ │ │ ├── FakeAuthenticationService.cs │ │ │ ├── FakeHttpContextAccessor.cs │ │ │ ├── HttpMessageExtensions.cs │ │ │ ├── TestAccessTokens.cs │ │ │ └── TokenHttpMessageHandler.cs │ ├── AccessTokenManagement.Tests.csproj │ ├── AccessTokenManagement.Tests.net8.0.v3.ncrunchproject │ ├── AccessTokenManagement.Tests.net9.0.v3.ncrunchproject │ ├── AccessTokenManagement.Tests.v3.ncrunchproject │ ├── BackChannelClientTests.cs │ ├── ClientTokenManagementApiTests.cs │ ├── ClientTokenManagementTests.cs │ ├── ConventionTests.cs │ ├── DPoPExtensionTests.cs │ ├── Framework │ │ ├── ApiHost.cs │ │ ├── AppHost.cs │ │ ├── FakeHybridCache.cs │ │ ├── FakeTimeProvider.cs │ │ ├── GenericHost.cs │ │ ├── IdentityServerHost.cs │ │ ├── IntegrationTestBase.cs │ │ ├── TestBrowserClient.cs │ │ ├── TestClientAssertionService.cs │ │ ├── TestDPoPNonceStore.cs │ │ ├── TestDPoPProofService.cs │ │ ├── TestData.cs │ │ ├── TestDataBuilder.cs │ │ ├── TestDistributedCache.cs │ │ ├── TestLoggerProvider.cs │ │ ├── TestOptionsMonitor.cs │ │ └── TestSchemeProvider.cs │ ├── HybridCacheExplorationTests.cs │ ├── LogExpirationTests.cs │ ├── PublicApiVerification.cs │ ├── PublicApiVerificationTests.GetAllPublicTypes.verified.txt │ ├── PublicApiVerificationTests.GetAllPublicTypes_OpenIdConnect.verified.txt │ ├── PublicApiVerificationTests.VerifyPublicApi.verified.txt │ ├── PublicApiVerificationTests.VerifyPublicApi_OpenIdConnect.verified.txt │ ├── StoreTokensInAuthenticationPropertiesTests.cs │ ├── TaskTimeoutExtensions.cs │ ├── Types │ │ ├── AccessTokenTypeTests.cs │ │ ├── ClientCredentialsCacheKeyTests.cs │ │ ├── TokenResultTests.cs │ │ └── ValidationRulesTests.cs │ ├── UserTokenManagementTests.cs │ ├── UserTokenManagementWithDPoPTests.cs │ └── Usings.cs │ └── Directory.Build.props ├── foss.sln.DotSettings ├── foss.slnx ├── foss.slnx.v3.ncrunchsolution ├── foss.v3.ncrunchsolution ├── global.json ├── icon.png ├── identity-model-oidc-client ├── .config │ └── dotnet-tools.json ├── .gitignore ├── README.md ├── clients │ ├── ConsoleClientWithBrowser │ │ ├── ConsoleClientWithBrowser.csproj │ │ ├── ConsoleClientWithBrowser.v3.ncrunchproject │ │ ├── Program.cs │ │ └── SystemBrowser.cs │ ├── ConsoleClientWithBrowserAndDPoP │ │ ├── ConsoleClientWithBrowserAndDPoP.csproj │ │ ├── ConsoleClientWithBrowserAndDPoP.v3.ncrunchproject │ │ ├── Program.cs │ │ └── SystemBrowser.cs │ ├── Directory.Build.props │ └── ManualModeConsoleClient │ │ ├── ManualModeConsoleClient.csproj │ │ ├── ManualModeConsoleClient.v3.ncrunchproject │ │ └── Program.cs ├── samples │ ├── Directory.Build.props │ ├── HttpSysConsoleClient │ │ ├── ConsoleSystemBrowser.sln │ │ ├── HttpSysConsoleClient │ │ │ ├── HttpSysConsoleClient.csproj │ │ │ └── Program.cs │ │ └── README.md │ ├── Maui │ │ ├── MauiApp1 │ │ │ ├── MauiApp1.sln │ │ │ └── MauiApp1 │ │ │ │ ├── App.xaml │ │ │ │ ├── App.xaml.cs │ │ │ │ ├── AppShell.xaml │ │ │ │ ├── AppShell.xaml.cs │ │ │ │ ├── MainPage.xaml │ │ │ │ ├── MainPage.xaml.cs │ │ │ │ ├── MauiApp1.csproj │ │ │ │ ├── MauiAuthenticationBrowser.cs │ │ │ │ ├── MauiProgram.cs │ │ │ │ ├── Platforms │ │ │ │ ├── Android │ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ │ ├── MainActivity.cs │ │ │ │ │ ├── MainApplication.cs │ │ │ │ │ ├── Resources │ │ │ │ │ │ └── values │ │ │ │ │ │ │ └── colors.xml │ │ │ │ │ └── WebAuthenticationCallbackActivity.cs │ │ │ │ ├── MacCatalyst │ │ │ │ │ ├── AppDelegate.cs │ │ │ │ │ ├── Entitlements.plist │ │ │ │ │ ├── Info.plist │ │ │ │ │ └── Program.cs │ │ │ │ ├── Tizen │ │ │ │ │ ├── Main.cs │ │ │ │ │ └── tizen-manifest.xml │ │ │ │ ├── Windows │ │ │ │ │ ├── App.xaml │ │ │ │ │ ├── App.xaml.cs │ │ │ │ │ ├── Package.appxmanifest │ │ │ │ │ └── app.manifest │ │ │ │ └── iOS │ │ │ │ │ ├── AppDelegate.cs │ │ │ │ │ ├── Info.plist │ │ │ │ │ └── Program.cs │ │ │ │ ├── Properties │ │ │ │ └── launchSettings.json │ │ │ │ └── Resources │ │ │ │ ├── AppIcon │ │ │ │ ├── appicon.svg │ │ │ │ └── appiconfg.svg │ │ │ │ ├── Fonts │ │ │ │ ├── OpenSans-Regular.ttf │ │ │ │ └── OpenSans-Semibold.ttf │ │ │ │ ├── Images │ │ │ │ └── dotnet_bot.png │ │ │ │ ├── Raw │ │ │ │ └── AboutAssets.txt │ │ │ │ ├── Splash │ │ │ │ └── splash.svg │ │ │ │ └── Styles │ │ │ │ ├── Colors.xaml │ │ │ │ └── Styles.xaml │ │ └── README.md │ ├── NetCoreConsoleClient │ │ ├── NetCoreConsoleClient.sln │ │ ├── README.md │ │ └── src │ │ │ └── NetCoreConsoleClient │ │ │ ├── NetCoreConsoleClient.csproj │ │ │ ├── Program.cs │ │ │ └── SystemBrowser.cs │ ├── README.md │ ├── WinFormsWebView2 │ │ ├── README.md │ │ ├── WinFormsWebView2.sln │ │ └── WinFormsWebView2 │ │ │ ├── App.config │ │ │ ├── Form1.Designer.cs │ │ │ ├── Form1.cs │ │ │ ├── Form1.resx │ │ │ ├── Program.cs │ │ │ ├── Properties │ │ │ ├── AssemblyInfo.cs │ │ │ ├── Resources.Designer.cs │ │ │ ├── Resources.resx │ │ │ ├── Settings.Designer.cs │ │ │ └── Settings.settings │ │ │ ├── WinFormsWebView.cs │ │ │ └── WinFormsWebView2.csproj │ ├── WindowsConsoleSystemBrowser │ │ ├── .vscode │ │ │ ├── launch.json │ │ │ └── tasks.json │ │ ├── README.md │ │ ├── WindowsConsoleSystemBrowser.sln │ │ └── WindowsConsoleSystemBrowser │ │ │ ├── CallbackManager.cs │ │ │ ├── Program.cs │ │ │ ├── RegistryConfig.cs │ │ │ ├── WindowsConsoleSystemBrowser.csproj │ │ │ └── callback.bat │ ├── Wpf │ │ ├── README.md │ │ ├── Wpf.sln │ │ └── Wpf │ │ │ ├── App.xaml │ │ │ ├── App.xaml.cs │ │ │ ├── AssemblyInfo.cs │ │ │ ├── CallbackManager.cs │ │ │ ├── DataProtector.cs │ │ │ ├── MainWindow.xaml │ │ │ ├── MainWindow.xaml.cs │ │ │ ├── RegistryConfig.cs │ │ │ ├── Session.cs │ │ │ └── Wpf.csproj │ └── WpfWebView2 │ │ ├── README.md │ │ ├── WpfWebView2.sln │ │ └── WpfWebView2 │ │ ├── App.xaml │ │ ├── App.xaml.cs │ │ ├── AssemblyInfo.cs │ │ ├── MainWindow.xaml │ │ ├── MainWindow.xaml.cs │ │ ├── WpfEmbeddedBrowser.cs │ │ └── WpfWebView2.csproj ├── src │ ├── Directory.Build.props │ ├── IdentityModel.OidcClient.Extensions │ │ ├── DPoP │ │ │ ├── DPoPExtensions.cs │ │ │ ├── DPoPProof.cs │ │ │ ├── DPoPProofPayload.cs │ │ │ ├── DPoPProofRequest.cs │ │ │ ├── DPoPProofTokenFactory.cs │ │ │ ├── JsonWebKeys.cs │ │ │ ├── OidcClientExtensions.cs │ │ │ ├── ProofTokenMessageHandler.cs │ │ │ └── SourceGenerationContext.cs │ │ ├── IdentityModel.OidcClient.Extensions.csproj │ │ ├── IdentityModel.OidcClient.Extensions.net6.0.v3.ncrunchproject │ │ ├── IdentityModel.OidcClient.Extensions.net8.0.v3.ncrunchproject │ │ ├── IdentityModel.OidcClient.Extensions.netstandard2.0.v3.ncrunchproject │ │ └── README.md │ ├── IdentityModel.OidcClient │ │ ├── AssemblyAttributes.cs │ │ ├── AuthorizeClient.cs │ │ ├── AuthorizeRequest.cs │ │ ├── AuthorizeState.cs │ │ ├── Browser │ │ │ ├── BrowserOptions.cs │ │ │ ├── BrowserResult.cs │ │ │ ├── BrowserResultType.cs │ │ │ ├── DisplayMode.cs │ │ │ └── IBrowser.cs │ │ ├── CryptoHelper.cs │ │ ├── IIdentityTokenValidator.cs │ │ ├── IdentityModel.OidcClient.csproj │ │ ├── IdentityModel.OidcClient.net6.0.v3.ncrunchproject │ │ ├── IdentityModel.OidcClient.net8.0.v3.ncrunchproject │ │ ├── IdentityModel.OidcClient.netstandard2.0.v3.ncrunchproject │ │ ├── Infrastructure │ │ │ ├── LogSerializer.cs │ │ │ ├── LoggingExtensions.cs │ │ │ ├── OidcClientOptionsExtensions.cs │ │ │ └── StringExtensions.cs │ │ ├── LoginRequest.cs │ │ ├── LoginResult.cs │ │ ├── LogoutRequest.cs │ │ ├── LogoutResult.cs │ │ ├── NoValidationIdentityTokenValidator.cs │ │ ├── OidcClient.cs │ │ ├── OidcClientOptions.cs │ │ ├── Policy.cs │ │ ├── ProviderInformation.cs │ │ ├── README.md │ │ ├── RefreshTokenDelegatingHandler.cs │ │ ├── ResponseProcessor.cs │ │ ├── ResponseValidationResult.cs │ │ ├── Result.cs │ │ ├── Results │ │ │ ├── AuthorizeResult.cs │ │ │ ├── IdentityTokenValidationResult.cs │ │ │ ├── RefreshTokenResult.cs │ │ │ ├── TokenResponseValidationResult.cs │ │ │ └── UserInfoResult.cs │ │ ├── SourceGenerationContext.cs │ │ └── TokenRefreshedEventArgs.cs │ └── TrimmableAnalysis │ │ ├── Program.cs │ │ ├── README.md │ │ ├── TrimmableAnalysis.csproj │ │ └── TrimmableAnalysis.v3.ncrunchproject └── test │ ├── Directory.Build.props │ └── IdentityModel.OidcClient.Tests │ ├── AuthorizeRequestTests.cs │ ├── CodeFlowResponseTests.cs │ ├── CommonResponseTests.cs │ ├── ConfigurationTests.cs │ ├── CryptoHelperTests.cs │ ├── DPoP │ ├── DPoPTests.cs │ └── Framework │ │ ├── ApiHost.cs │ │ ├── DPoP │ │ ├── ConfigureJwtBearerOptions.cs │ │ ├── DPoPExtensions.cs │ │ ├── DPoPJwtBearerEvents.cs │ │ ├── DPoPMode.cs │ │ ├── DPoPOptions.cs │ │ ├── DPoPProofValidatonContext.cs │ │ ├── DPoPProofValidatonResult.cs │ │ ├── DPoPProofValidator.cs │ │ ├── DPoPServiceCollectionExtensions.cs │ │ ├── DefaultReplayCache.cs │ │ └── IReplayCache.cs │ │ ├── GenericHost.cs │ │ ├── IdentityServerHost.cs │ │ ├── IntegrationTestBase.cs │ │ └── TestLoggerProvider.cs │ ├── DPoPExtensionTests.cs │ ├── EndSessionUrlTests.cs │ ├── IdentityModel.OidcClient.Tests.csproj │ ├── IdentityModel.OidcClient.Tests.net6.0.v3.ncrunchproject │ ├── IdentityModel.OidcClient.Tests.net8.0.v3.ncrunchproject │ ├── IdentityModel.OidcClient.Tests.net9.0.v3.ncrunchproject │ ├── Infrastructure │ ├── Crypto.cs │ ├── NetworkHandler.cs │ └── QueryHelpers.cs │ ├── LogSerializerTests.cs │ ├── OidcClientTests.cs │ ├── RefreshTokenDelegatingHandlerTests.cs │ └── TestBrowser.cs ├── identity-model ├── .config │ └── dotnet-tools.json ├── README.md ├── samples │ └── HttpClientFactory │ │ ├── Controllers │ │ └── HomeController.cs │ │ ├── HttpClientFactory.csproj │ │ ├── HttpClientFactory.v3.ncrunchproject │ │ ├── Models │ │ └── ErrorViewModel.cs │ │ ├── Program.cs │ │ ├── Properties │ │ └── launchSettings.json │ │ ├── Startup.cs │ │ ├── Views │ │ ├── Home │ │ │ └── Index.cshtml │ │ ├── Shared │ │ │ ├── Error.cshtml │ │ │ ├── _CookieConsentPartial.cshtml │ │ │ ├── _Layout.cshtml │ │ │ └── _ValidationScriptsPartial.cshtml │ │ ├── _ViewImports.cshtml │ │ └── _ViewStart.cshtml │ │ ├── appsettings.Development.json │ │ ├── appsettings.json │ │ └── wwwroot │ │ ├── css │ │ ├── site.css │ │ └── site.min.css │ │ ├── favicon.ico │ │ ├── images │ │ ├── banner1.svg │ │ ├── banner2.svg │ │ └── banner3.svg │ │ ├── js │ │ ├── site.js │ │ └── site.min.js │ │ └── lib │ │ ├── bootstrap │ │ ├── .bower.json │ │ ├── LICENSE │ │ └── dist │ │ │ ├── css │ │ │ ├── bootstrap-theme.css │ │ │ ├── bootstrap-theme.css.map │ │ │ ├── bootstrap-theme.min.css │ │ │ ├── bootstrap-theme.min.css.map │ │ │ ├── bootstrap.css │ │ │ ├── bootstrap.css.map │ │ │ ├── bootstrap.min.css │ │ │ └── bootstrap.min.css.map │ │ │ ├── fonts │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ ├── glyphicons-halflings-regular.svg │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ ├── glyphicons-halflings-regular.woff │ │ │ └── glyphicons-halflings-regular.woff2 │ │ │ └── js │ │ │ ├── bootstrap.js │ │ │ ├── bootstrap.min.js │ │ │ └── npm.js │ │ ├── jquery-validation-unobtrusive │ │ ├── .bower.json │ │ ├── LICENSE.txt │ │ ├── jquery.validate.unobtrusive.js │ │ └── jquery.validate.unobtrusive.min.js │ │ ├── jquery-validation │ │ ├── .bower.json │ │ ├── LICENSE.md │ │ └── dist │ │ │ ├── additional-methods.js │ │ │ ├── additional-methods.min.js │ │ │ ├── jquery.validate.js │ │ │ └── jquery.validate.min.js │ │ └── jquery │ │ ├── .bower.json │ │ ├── LICENSE.txt │ │ └── dist │ │ ├── jquery.js │ │ ├── jquery.min.js │ │ └── jquery.min.map ├── src │ ├── Directory.Build.props │ ├── IdentityModel │ │ ├── Base64Url.cs │ │ ├── ClaimComparer.cs │ │ ├── Client │ │ │ ├── AuthorityUrlValidationStrategy.cs │ │ │ ├── AuthorityValidationResult.cs │ │ │ ├── AuthorizationHeaderExtensions.cs │ │ │ ├── BasicAuthenticationHeaderStyle.cs │ │ │ ├── BasicAuthenticationHeaderValue.cs │ │ │ ├── BasicAuthenticationOAuthHeaderValue.cs │ │ │ ├── ClientCredentialStyle.cs │ │ │ ├── ClientOptions.cs │ │ │ ├── DiscoveryCache.cs │ │ │ ├── DiscoveryEndpoint.cs │ │ │ ├── DiscoveryPolicy.cs │ │ │ ├── HttpClientBackchannelAuthenticationExtensions.cs │ │ │ ├── HttpClientDeviceFlowExtensions.cs │ │ │ ├── HttpClientDiscoveryExtensions.cs │ │ │ ├── HttpClientDynamicRegistrationExtensions.cs │ │ │ ├── HttpClientJsonWebKeySetExtensions.cs │ │ │ ├── HttpClientPushedAuthorizationExtensions.cs │ │ │ ├── HttpClientTokenIntrospectionExtensions.cs │ │ │ ├── HttpClientTokenRequestExtensions.cs │ │ │ ├── HttpClientTokenRevocationExtensions.cs │ │ │ ├── HttpClientUserInfoExtensions.cs │ │ │ ├── IAuthorityValidationStrategy.cs │ │ │ ├── IDiscoveryCache.cs │ │ │ ├── IntrospectionClient.cs │ │ │ ├── JsonElementExtensions.cs │ │ │ ├── Messages │ │ │ │ ├── AuthorizationCodeTokenRequest.cs │ │ │ │ ├── AuthorizeResponse.cs │ │ │ │ ├── BackchannelAuthenticationRequest.cs │ │ │ │ ├── BackchannelAuthenticationResponse.cs │ │ │ │ ├── BackchannelAuthenticationTokenRequest.cs │ │ │ │ ├── ClientAssertion.cs │ │ │ │ ├── ClientCredentialsTokenRequest.cs │ │ │ │ ├── ClientMessagesSourceGenerationContext.cs │ │ │ │ ├── DeviceAuthorizationRequest.cs │ │ │ │ ├── DeviceAuthorizationResponse.cs │ │ │ │ ├── DeviceTokenRequest.cs │ │ │ │ ├── DiscoveryDocumentRequest.cs │ │ │ │ ├── DiscoveryDocumentResponse.cs │ │ │ │ ├── DynamicClientRegistrationDocument.cs │ │ │ │ ├── DynamicClientRegistrationRequest.cs │ │ │ │ ├── DynamicClientRegistrationResponse.cs │ │ │ │ ├── JsonWebKeySetRequest.cs │ │ │ │ ├── JsonWebKeySetResponse.cs │ │ │ │ ├── MtlsEndpointAliases.cs │ │ │ │ ├── ParameterReplaceBehavior.cs │ │ │ │ ├── Parameters.cs │ │ │ │ ├── PasswordTokenRequest.cs │ │ │ │ ├── ProtocolRequest.cs │ │ │ │ ├── ProtocolResponse.cs │ │ │ │ ├── PushedAuthorizationRequest.cs │ │ │ │ ├── PushedAuthorizationResponse.cs │ │ │ │ ├── RefreshTokenRequest.cs │ │ │ │ ├── ResponseErrorType.cs │ │ │ │ ├── TokenExchangeTokenRequest.cs │ │ │ │ ├── TokenIntrospectionRequest.cs │ │ │ │ ├── TokenIntrospectionResponse.cs │ │ │ │ ├── TokenRequest.cs │ │ │ │ ├── TokenResponse.cs │ │ │ │ ├── TokenRevocationRequest.cs │ │ │ │ ├── TokenRevocationResponse.cs │ │ │ │ ├── UserInfoRequest.cs │ │ │ │ └── UserInfoResponse.cs │ │ │ ├── RequestUrl.cs │ │ │ ├── RequestUrlExtensions.cs │ │ │ ├── ResponseFormat.cs │ │ │ ├── StringComparisonAuthorityValidationStrategy.cs │ │ │ └── TokenClient.cs │ │ ├── CryptoRandom.cs │ │ ├── DateTimeExtensions.cs │ │ ├── Identity.cs │ │ ├── IdentityModel.csproj │ │ ├── Internal │ │ │ ├── AsyncLazy.cs │ │ │ ├── QueryHelpers.cs │ │ │ ├── StringExtensions.cs │ │ │ └── TaskHelpers.cs │ │ ├── Jwk │ │ │ ├── JsonWebAlgorithmsKeyTypes.cs │ │ │ ├── JsonWebKeyParameterNames.cs │ │ │ ├── JsonWebKeySet.cs │ │ │ ├── JsonWebkey.cs │ │ │ ├── JwkExtensions.cs │ │ │ └── JwkSourceGenerationContext.cs │ │ ├── JwtClaimTypes.cs │ │ ├── OidcConstants.cs │ │ ├── Principal.cs │ │ ├── StringExtensions.cs │ │ ├── TimeConstantComparer.cs │ │ ├── Validation │ │ │ └── ITokenIntrospectionJwtResponseValidator.cs │ │ ├── X509.cs │ │ ├── X509CertificatesFinder.cs │ │ ├── X509CertificatesLocation.cs │ │ └── X509CertificatesName.cs │ └── TrimmableAnalysis │ │ ├── Program.cs │ │ ├── README.md │ │ └── TrimmableAnalysis.csproj └── test │ ├── Directory.Build.props │ └── IdentityModel.Tests │ ├── AuthorizeResponseTests.cs │ ├── BasicAuthenticationEncodingTests.cs │ ├── ClaimsComparisonTests.cs │ ├── DiscoveryCacheTests.cs │ ├── DiscoveryPolicyTestsBase.cs │ ├── DiscoveryPolicyTests_AuthorityStringComparison.cs │ ├── DiscoveryPolicyTests_AuthorityUriComparison.cs │ ├── DiscoveryPolicyTests_WithoutAuthorityValidation.cs │ ├── GlobalUsings.cs │ ├── HttpClientExtensions │ ├── CibaExtensionsTests.cs │ ├── DeviceAuthorizationExtensionsTests.cs │ ├── DiscoveryExtensionsTests.cs │ ├── DynamicClientRegistrationTests.cs │ ├── HttpRequestMethodExtensions.cs │ ├── JsonWebKeyExtensionsTests.cs │ ├── PushedAuthorizationTests.cs │ ├── TokenIntrospectionTests.cs │ ├── TokenRequestExtensionsRequestTests.cs │ ├── TokenRequestExtensionsResponseTests.cs │ ├── TokenRevocationExtensions.cs │ └── UserInfoExtensionsTests.cs │ ├── IdentityModel.Tests.csproj │ ├── IdentityModel.Tests.net481.v3.ncrunchproject │ ├── Infrastructure │ ├── FileName.cs │ └── NetworkHandler.cs │ ├── Internal │ └── ParametersTest.cs │ ├── RequestUrlTests.cs │ ├── ShouldlyExtensions.cs │ ├── TokenClientRequestTests.cs │ ├── Verifications │ ├── PublicApiVerificationTests.VerifyPublicApi.verified.txt │ └── PublicApiVerificationTests.cs │ └── documents │ ├── discovery.json │ ├── discovery_jwks.json │ ├── discovery_mtls.json │ ├── discovery_variable.json │ ├── failure_device_authorization_response.json │ ├── failure_registration_response.json │ ├── failure_token_response.json │ ├── failure_token_revocation_response.json │ ├── legacy_success_introspection_response.json │ ├── success_access_token_response.json │ ├── success_ciba_response.json │ ├── success_device_authorization_response.json │ ├── success_introspection_response.json │ ├── success_introspection_response.jwt │ ├── success_introspection_response_no_issuer.json │ ├── success_par_response.json │ ├── success_registration_response.json │ ├── success_token_response.json │ ├── success_userinfo_response.json │ └── success_userinfo_response.jwt ├── ignore-this ├── .config │ └── dotnet-tools.json ├── README.md ├── src │ ├── Directory.Build.props │ └── IgnoreThis │ │ └── IgnoreThis.csproj └── test │ ├── Directory.Build.props │ └── IgnoreThis.Tests │ ├── Class1.cs │ ├── IgnoreThis.Tests.csproj │ └── Usings.cs ├── key.snk ├── samples.props ├── src.props └── test.props /.gitattributes: -------------------------------------------------------------------------------- 1 | *.verified.txt text eol=lf working-tree-encoding=UTF-8 2 | *.verified.xml text eol=lf working-tree-encoding=UTF-8 3 | *.verified.json text eol=lf working-tree-encoding=UTF-8 -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | /.github @DuendeSoftware/product-owners 2 | /access-token-management/ @DuendeSoftware/team-bff 3 | /identity-model/ @DuendeSoftware/team-is 4 | /identity-model-oidc-client/ @DuendeSoftware/team-is -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Support Forum 4 | url: https://github.com/DuendeSoftware/community 5 | about: The place for questions, support and feature requests 6 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | **What issue does this PR address?** 2 | 3 | 4 | -------------------------------------------------------------------------------- /.github/workflow-gen/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "workflow-gen": { 4 | "commandName": "Project", 5 | "workingDirectory": "$(ProjectDir)" 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /.github/workflow-gen/workflow-gen.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | net8.0 6 | workflow_gen 7 | enable 8 | enable 9 | false 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /.github/workflows/codeql.yml: -------------------------------------------------------------------------------- 1 | name: codeql 2 | 3 | on: 4 | schedule: 5 | - cron: '38 15 * * 0' 6 | 7 | jobs: 8 | analyze: 9 | name: Analyze 10 | runs-on: ubuntu-latest 11 | permissions: 12 | actions: read 13 | contents: read 14 | security-events: write 15 | 16 | steps: 17 | - name: Checkout repository 18 | uses: actions/checkout@v4 19 | 20 | - name: Initialize CodeQL 21 | uses: github/codeql-action/init@ea9e4e37992a54ee68a9622e985e60c8e8f12d9f # 3.27.4 22 | with: 23 | languages: csharp 24 | 25 | - name: Auto build 26 | uses: github/codeql-action/autobuild@ea9e4e37992a54ee68a9622e985e60c8e8f12d9f # 3.27.4 27 | 28 | - name: Perform CodeQL analysis 29 | uses: github/codeql-action/analyze@ea9e4e37992a54ee68a9622e985e60c8e8f12d9f # 3.27.4 30 | with: 31 | category: "/language:csharp" 32 | -------------------------------------------------------------------------------- /access-token-management/.config/dotnet-tools.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1, 3 | "isRoot": true, 4 | "tools": { 5 | "NuGetKeyVaultSignTool": { 6 | "version": "3.2.3", 7 | "commands": [ 8 | "NuGetKeyVaultSignTool" 9 | ] 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /access-token-management/perf/.gitignore: -------------------------------------------------------------------------------- 1 | keys/ -------------------------------------------------------------------------------- /access-token-management/perf/Perf.DevServer/Perf.DevServer.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Exe 7 | net9.0 8 | enable 9 | enable 10 | true 11 | ae9c3359-f558-4952-a4ad-4af16537b25f 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /access-token-management/perf/Perf.DevServer/Perf.DevServer.v3.ncrunchproject: -------------------------------------------------------------------------------- 1 |  2 | 3 | True 4 | 5 | -------------------------------------------------------------------------------- /access-token-management/perf/Perf.DevServer/Program.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | using Microsoft.Extensions.Hosting; 5 | 6 | var builder = DistributedApplication.CreateBuilder(args); 7 | 8 | var cache = builder.AddRedis("cache") 9 | .WithRedisCommander(); 10 | 11 | var idServer = builder.AddProject(Services.IdentityServer.ToString()); 12 | 13 | var tokenEndpoint = builder.AddProject(Services.TokenEndpoint.ToString()) 14 | .WithReplicas(3) 15 | .WithReference(cache); 16 | ; 17 | 18 | idServer.WithReference(tokenEndpoint); 19 | tokenEndpoint.WithReference(idServer); 20 | 21 | 22 | 23 | builder.Build().Run(); 24 | -------------------------------------------------------------------------------- /access-token-management/perf/Perf.DevServer/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/launchsettings.json", 3 | "profiles": { 4 | "https": { 5 | "commandName": "Project", 6 | "dotnetRunMessages": true, 7 | "launchBrowser": true, 8 | "applicationUrl": "https://localhost:17294;http://localhost:15153", 9 | "environmentVariables": { 10 | "ASPNETCORE_ENVIRONMENT": "Development", 11 | "DOTNET_ENVIRONMENT": "Development", 12 | "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:21203", 13 | "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:22103" 14 | } 15 | }, 16 | "http": { 17 | "commandName": "Project", 18 | "dotnetRunMessages": true, 19 | "launchBrowser": true, 20 | "applicationUrl": "http://localhost:15153", 21 | "environmentVariables": { 22 | "ASPNETCORE_ENVIRONMENT": "Development", 23 | "DOTNET_ENVIRONMENT": "Development", 24 | "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:19188", 25 | "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:20190" 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /access-token-management/perf/Perf.DevServer/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /access-token-management/perf/Perf.DevServer/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning", 6 | "Aspire.Hosting.Dcp": "Warning" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /access-token-management/perf/Perf.IdentityServer/Perf.IdentityServer.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /access-token-management/perf/Perf.IdentityServer/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "SelfHost": { 4 | "commandName": "Project", 5 | "launchBrowser": true, 6 | "environmentVariables": { 7 | "ASPNETCORE_ENVIRONMENT": "Development" 8 | }, 9 | "applicationUrl": "https://localhost:5001" 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /access-token-management/perf/Perf.IdentityServer/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Serilog": { 3 | "MinimumLevel": { 4 | "Default": "Debug", 5 | "Override": { 6 | "Microsoft": "Warning", 7 | "Microsoft.Hosting.Lifetime": "Information", 8 | "Microsoft.AspNetCore.Authentication": "Debug", 9 | "System": "Warning" 10 | } 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /access-token-management/perf/Perf.K6/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "perf.k6", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "perf.k6", 9 | "version": "1.0.0", 10 | "license": "ISC", 11 | "devDependencies": { 12 | "@types/k6": "^0.57.1" 13 | } 14 | }, 15 | "node_modules/@types/k6": { 16 | "version": "0.57.1", 17 | "resolved": "https://registry.npmjs.org/@types/k6/-/k6-0.57.1.tgz", 18 | "integrity": "sha512-S/p2RQAYUBXyYROkR2fgeON/LaxJ0YR+KIlnPQW/TOeLBXD7tX4RfDSWaIecuDTWKblmc6UwANyP0e5QDZPhMw==", 19 | "dev": true, 20 | "license": "MIT" 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /access-token-management/perf/Perf.K6/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "perf.k6", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "scripts": { 6 | "test": "echo \"Error: no test specified\" && exit 1" 7 | }, 8 | "keywords": [], 9 | "author": "", 10 | "license": "ISC", 11 | "type": "commonjs", 12 | "description": "", 13 | "devDependencies": { 14 | "@types/k6": "^0.57.1" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /access-token-management/perf/Perf.K6/token.ts: -------------------------------------------------------------------------------- 1 | import http from "k6/http"; 2 | 3 | export const options = { 4 | vus: 10, 5 | duration: '30s', 6 | }; 7 | 8 | 9 | export default function() { 10 | let res = http.get("https://localhost:7270/token"); 11 | console.log(res.status); 12 | } -------------------------------------------------------------------------------- /access-token-management/perf/Perf.TokenEndpoint/Perf.TokenEndpoint.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /access-token-management/perf/Perf.TokenEndpoint/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/launchsettings.json", 3 | "profiles": { 4 | "http": { 5 | "commandName": "Project", 6 | "dotnetRunMessages": true, 7 | "launchBrowser": false, 8 | "applicationUrl": "http://localhost:5237", 9 | "environmentVariables": { 10 | "ASPNETCORE_ENVIRONMENT": "Development" 11 | } 12 | }, 13 | "https": { 14 | "commandName": "Project", 15 | "dotnetRunMessages": true, 16 | "launchBrowser": false, 17 | "applicationUrl": "https://localhost:7270;http://localhost:5237", 18 | "environmentVariables": { 19 | "ASPNETCORE_ENVIRONMENT": "Development" 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /access-token-management/perf/Perf.TokenEndpoint/TokenEndpoint.http: -------------------------------------------------------------------------------- 1 | @TokenEndpoint_HostAddress = http://localhost:5237 2 | 3 | GET {{TokenEndpoint_HostAddress}}/weatherforecast/ 4 | Accept: application/json 5 | 6 | ### 7 | -------------------------------------------------------------------------------- /access-token-management/perf/Perf.TokenEndpoint/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /access-token-management/perf/Perf.TokenEndpoint/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /access-token-management/samples/BlazorServer/BlazorServer.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | aspnet-BlazorServer-AF0F1063-736A-4F96-BAF4-B06CE5D44F0D 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /access-token-management/samples/BlazorServer/BlazorServer.v3.ncrunchproject: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | LostReference 5 | 6 | 7 | -------------------------------------------------------------------------------- /access-token-management/samples/BlazorServer/Data/WeatherForecast.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | namespace BlazorServer.Services; 5 | 6 | public class WeatherForecast 7 | { 8 | public DateTime Date { get; set; } 9 | 10 | public int TemperatureC { get; set; } 11 | 12 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); 13 | 14 | public string? Summary { get; set; } 15 | } 16 | -------------------------------------------------------------------------------- /access-token-management/samples/BlazorServer/Pages/Counter.razor: -------------------------------------------------------------------------------- 1 | @page "/counter" 2 | 3 | Counter 4 | 5 |

Counter

6 | 7 |

Current count: @currentCount

8 | 9 | 10 | 11 | @code { 12 | private int currentCount = 0; 13 | 14 | private void IncrementCount() 15 | { 16 | currentCount++; 17 | } 18 | 19 | } -------------------------------------------------------------------------------- /access-token-management/samples/BlazorServer/Pages/Error.cshtml.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | using System.Diagnostics; 5 | using Microsoft.AspNetCore.Mvc; 6 | using Microsoft.AspNetCore.Mvc.RazorPages; 7 | 8 | namespace BlazorServer.Pages; 9 | 10 | [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] 11 | [IgnoreAntiforgeryToken] 12 | public class ErrorModel : PageModel 13 | { 14 | public string? RequestId { get; set; } 15 | 16 | public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); 17 | 18 | private readonly ILogger _logger; 19 | 20 | public ErrorModel(ILogger logger) => _logger = logger; 21 | 22 | public void OnGet() => RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier; 23 | } 24 | -------------------------------------------------------------------------------- /access-token-management/samples/BlazorServer/Pages/FetchRemoteData.razor: -------------------------------------------------------------------------------- 1 | @page "/fetchremotedata" 2 | 3 | Remote API 4 | 5 | @attribute [Authorize] 6 | 7 | @using BlazorServer.Services 8 | @inject RemoteApiService Service 9 | 10 |

Remote API

11 | 12 |

This component demonstrates fetching data from a remote API.

13 | 14 | @if (data == null) 15 | { 16 |

17 | Loading... 18 |

19 | } 20 | else 21 | { 22 |
23 |         @data
24 |     
25 | } 26 | 27 | @code { 28 | private string? data = null; 29 | 30 | protected override async Task OnInitializedAsync() 31 | { 32 | data = await Service.GetData(); 33 | } 34 | } -------------------------------------------------------------------------------- /access-token-management/samples/BlazorServer/Pages/Index.razor: -------------------------------------------------------------------------------- 1 | @page "/" 2 | @using System.Security.Claims 3 | @inject AuthenticationStateProvider AuthenticationStateProvider 4 | 5 | Index 6 | 7 |

Hello, world!

8 | 9 | @if (User?.Identity?.IsAuthenticated == true) 10 | { 11 |

Welcome, @User.Identity.Name!

12 | } 13 | else 14 | { 15 |

Welcome to our app!

16 |

You are not authenticated.

17 |

Please log in to continue.

18 | } 19 | 20 | 21 | 22 | @code { 23 | private ClaimsPrincipal? User { get; set; } 24 | 25 | protected override async Task OnInitializedAsync() 26 | { 27 | var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync(); 28 | User = authState.User; 29 | } 30 | } -------------------------------------------------------------------------------- /access-token-management/samples/BlazorServer/Plumbing/AccountController.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | using Microsoft.AspNetCore.Authentication; 5 | using Microsoft.AspNetCore.Authorization; 6 | using Microsoft.AspNetCore.Mvc; 7 | 8 | namespace BlazorServer.Plumbing; 9 | 10 | [AllowAnonymous] 11 | public class AccountController : ControllerBase 12 | { 13 | public IActionResult LogIn(string? returnUrl) 14 | { 15 | var redirectUri = "/"; 16 | 17 | if (!string.IsNullOrWhiteSpace(returnUrl)) 18 | { 19 | if (Url.IsLocalUrl(returnUrl)) 20 | { 21 | redirectUri = returnUrl; 22 | } 23 | } 24 | 25 | var props = new AuthenticationProperties 26 | { 27 | RedirectUri = redirectUri 28 | }; 29 | 30 | return Challenge(props); 31 | } 32 | 33 | public IActionResult LogOut() => SignOut("cookie", "oidc"); 34 | } 35 | -------------------------------------------------------------------------------- /access-token-management/samples/BlazorServer/Plumbing/CookieEvents.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | using Duende.AccessTokenManagement.OpenIdConnect; 5 | using Microsoft.AspNetCore.Authentication.Cookies; 6 | 7 | namespace BlazorServer.Plumbing; 8 | 9 | public class CookieEvents : CookieAuthenticationEvents 10 | { 11 | private readonly IUserTokenStore _store; 12 | 13 | public CookieEvents(IUserTokenStore store) => _store = store; 14 | 15 | public override async Task ValidatePrincipal(CookieValidatePrincipalContext context) 16 | { 17 | var token = await _store.GetTokenAsync(context.Principal!); 18 | if (!token.Succeeded) 19 | { 20 | context.RejectPrincipal(); 21 | } 22 | 23 | await base.ValidatePrincipal(context); 24 | } 25 | 26 | public override async Task SigningOut(CookieSigningOutContext context) 27 | { 28 | await context.HttpContext.RevokeRefreshTokenAsync(); 29 | 30 | await base.SigningOut(context); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /access-token-management/samples/BlazorServer/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "BlazorServer": { 4 | "commandName": "Project", 5 | "dotnetRunMessages": true, 6 | "launchBrowser": true, 7 | "applicationUrl": "https://localhost:7242", 8 | "environmentVariables": { 9 | "ASPNETCORE_ENVIRONMENT": "Development" 10 | } 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /access-token-management/samples/BlazorServer/Routes.razor: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | @if (context.User.Identity?.IsAuthenticated != true) 7 | { 8 | 9 | } 10 | else 11 | { 12 |

You are not authorized to access this resource.

13 | } 14 |
15 |
16 | 17 |
18 | 19 | Not found 20 | 21 |

Sorry, there's nothing at this address.

22 |
23 |
24 |
25 |
-------------------------------------------------------------------------------- /access-token-management/samples/BlazorServer/Services/RemoteApiService.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | using System.Text.Json; 5 | 6 | namespace BlazorServer.Services; 7 | 8 | public class RemoteApiService 9 | { 10 | private readonly HttpClient _client; 11 | 12 | public RemoteApiService(IHttpClientFactory factory) => _client = factory.CreateClient("demoApiClient"); 13 | 14 | private record Claim(string type, object value); 15 | 16 | public async Task GetData() 17 | { 18 | var response = await _client.GetStringAsync("test"); 19 | var json = JsonSerializer.Deserialize>(response); 20 | return JsonSerializer.Serialize(json, new JsonSerializerOptions { WriteIndented = true }); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /access-token-management/samples/BlazorServer/Services/WeatherForecastService.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | namespace BlazorServer.Services; 5 | 6 | public class WeatherForecastService 7 | { 8 | private static readonly string[] Summaries = new[] 9 | { 10 | "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" 11 | }; 12 | 13 | public Task GetForecastAsync(DateTime startDate) => Task.FromResult(Enumerable.Range(1, 5).Select(index => new WeatherForecast 14 | { 15 | Date = startDate.AddDays(index), 16 | TemperatureC = Random.Shared.Next(-20, 55), 17 | Summary = Summaries[Random.Shared.Next(Summaries.Length)] 18 | }).ToArray()); 19 | } 20 | -------------------------------------------------------------------------------- /access-token-management/samples/BlazorServer/Shared/LoginDisplay.razor: -------------------------------------------------------------------------------- 1 | 2 | 3 | Hello, @context.User.Identity!.Name 4 | Log out 5 | 6 | 7 | Log in 8 | 9 | -------------------------------------------------------------------------------- /access-token-management/samples/BlazorServer/Shared/MainLayout.razor: -------------------------------------------------------------------------------- 1 | @inherits LayoutComponentBase 2 | 3 | BlazorServer 4 | 5 |
6 | 9 | 10 |
11 |
12 | 13 |
14 | 15 |
16 | @Body 17 |
18 |
19 |
-------------------------------------------------------------------------------- /access-token-management/samples/BlazorServer/Shared/RedirectToLogin.razor: -------------------------------------------------------------------------------- 1 | @inject NavigationManager Navigation 2 | 3 | @code { 4 | // Using the async method prevents NavigationExceptions, even though this method is synchronous 5 | #pragma warning disable CS1998 6 | protected override async Task OnInitializedAsync() 7 | { 8 | var returnUrl = Uri.EscapeDataString("/" + Navigation.ToBaseRelativePath(Navigation.Uri)); 9 | Navigation.NavigateTo($"account/login?returnUrl={returnUrl}", forceLoad: true); 10 | } 11 | #pragma warning restore CS1998 12 | } -------------------------------------------------------------------------------- /access-token-management/samples/BlazorServer/Shared/SurveyPrompt.razor: -------------------------------------------------------------------------------- 1 |
2 | 3 | @Title 4 | 5 | 6 | Please take our 7 | brief survey 8 | 9 | and tell us what you think. 10 |
11 | 12 | @code { 13 | // Demonstrates how a parent component can supply parameters 14 | [Parameter] 15 | public string? Title { get; set; } 16 | 17 | } -------------------------------------------------------------------------------- /access-token-management/samples/BlazorServer/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http 2 | @using Microsoft.AspNetCore.Authorization 3 | @using Microsoft.AspNetCore.Components.Authorization 4 | @using Microsoft.AspNetCore.Components.Forms 5 | @using Microsoft.AspNetCore.Components.Routing 6 | @using Microsoft.AspNetCore.Components.Web 7 | @using Microsoft.AspNetCore.Components.Web.Virtualization 8 | @using Microsoft.JSInterop 9 | @using BlazorServer 10 | @using BlazorServer.Shared 11 | @using static Microsoft.AspNetCore.Components.Web.RenderMode -------------------------------------------------------------------------------- /access-token-management/samples/BlazorServer/wwwroot/css/open-iconic/font/fonts/open-iconic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DuendeSoftware/foss/4e49d6b9dca55d8b6746d24256c93cb301156346/access-token-management/samples/BlazorServer/wwwroot/css/open-iconic/font/fonts/open-iconic.eot -------------------------------------------------------------------------------- /access-token-management/samples/BlazorServer/wwwroot/css/open-iconic/font/fonts/open-iconic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DuendeSoftware/foss/4e49d6b9dca55d8b6746d24256c93cb301156346/access-token-management/samples/BlazorServer/wwwroot/css/open-iconic/font/fonts/open-iconic.otf -------------------------------------------------------------------------------- /access-token-management/samples/BlazorServer/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DuendeSoftware/foss/4e49d6b9dca55d8b6746d24256c93cb301156346/access-token-management/samples/BlazorServer/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf -------------------------------------------------------------------------------- /access-token-management/samples/BlazorServer/wwwroot/css/open-iconic/font/fonts/open-iconic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DuendeSoftware/foss/4e49d6b9dca55d8b6746d24256c93cb301156346/access-token-management/samples/BlazorServer/wwwroot/css/open-iconic/font/fonts/open-iconic.woff -------------------------------------------------------------------------------- /access-token-management/samples/BlazorServer/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DuendeSoftware/foss/4e49d6b9dca55d8b6746d24256c93cb301156346/access-token-management/samples/BlazorServer/wwwroot/favicon.ico -------------------------------------------------------------------------------- /access-token-management/samples/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /access-token-management/samples/Web/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "Web": { 4 | "commandName": "Project", 5 | "launchBrowser": true, 6 | "applicationUrl": "https://localhost:5002", 7 | "environmentVariables": { 8 | "ASPNETCORE_ENVIRONMENT": "Development" 9 | } 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /access-token-management/samples/Web/TypedClient.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | namespace Web; 5 | 6 | public abstract class TypedClient 7 | { 8 | private readonly HttpClient _client; 9 | 10 | public TypedClient(HttpClient client) => _client = client; 11 | 12 | public virtual async Task CallApi() => await _client.GetStringAsync("test"); 13 | } 14 | 15 | public class TypedUserClient : TypedClient 16 | { 17 | public TypedUserClient(HttpClient client) : base(client) 18 | { 19 | } 20 | } 21 | 22 | public class TypedClientClient : TypedClient 23 | { 24 | public TypedClientClient(HttpClient client) : base(client) 25 | { 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /access-token-management/samples/Web/Views/Home/CallApi.cshtml: -------------------------------------------------------------------------------- 1 | 

API Response

2 | 3 |
@ViewBag.Json
-------------------------------------------------------------------------------- /access-token-management/samples/Web/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | @using Microsoft.AspNetCore.Mvc.TagHelpers 2 | @using Microsoft.Extensions.Options 3 | @inject IOptions Options 4 | @{ 5 | ViewData["Title"] = "Home Page"; 6 | } 7 | 8 |

Call API as Client

9 | 10 | @if (!Options.Value.UseDPoP) 11 | { 12 | Extension method 13 | @("|") 14 | } 15 | HTTP client factory 16 | @("|") 17 | HTTP client factory (typed) 18 | @("|") 19 | Use resource indicator 20 | -------------------------------------------------------------------------------- /access-token-management/samples/Web/Views/Shared/_ValidationScriptsPartial.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | -------------------------------------------------------------------------------- /access-token-management/samples/Web/Views/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @using Web 2 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 3 | -------------------------------------------------------------------------------- /access-token-management/samples/Web/Views/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "_Layout"; 3 | } 4 | -------------------------------------------------------------------------------- /access-token-management/samples/Web/Web.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net9.0 5 | enable 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /access-token-management/samples/Web/Web.v3.ncrunchproject: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | LostReference 5 | 6 | 7 | -------------------------------------------------------------------------------- /access-token-management/samples/Web/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "BaseUrl": "https://demo.duendesoftware.com", 3 | "UseDPoP": true 4 | } 5 | -------------------------------------------------------------------------------- /access-token-management/samples/Web/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DuendeSoftware/foss/4e49d6b9dca55d8b6746d24256c93cb301156346/access-token-management/samples/Web/wwwroot/favicon.ico -------------------------------------------------------------------------------- /access-token-management/samples/Web/wwwroot/js/site.js: -------------------------------------------------------------------------------- 1 | // Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification 2 | // for details on configuring this project to bundle and minify static web assets. 3 | 4 | // Write your JavaScript code. 5 | -------------------------------------------------------------------------------- /access-token-management/samples/Web/wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) .NET Foundation. All rights reserved. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use 4 | these files except in compliance with the License. You may obtain a copy of the 5 | License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software distributed 10 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 11 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | specific language governing permissions and limitations under the License. 13 | -------------------------------------------------------------------------------- /access-token-management/samples/WebJarJwt/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "WebJarJwt": { 4 | "commandName": "Project", 5 | "launchBrowser": true, 6 | "environmentVariables": { 7 | "ASPNETCORE_ENVIRONMENT": "Development" 8 | }, 9 | "applicationUrl": "https://localhost:44302" 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /access-token-management/samples/WebJarJwt/TypedClient.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | namespace WebJarJwt; 5 | 6 | public abstract class TypedClient 7 | { 8 | private readonly HttpClient _client; 9 | 10 | public TypedClient(HttpClient client) => _client = client; 11 | 12 | public virtual async Task CallApi() => await _client.GetStringAsync("test"); 13 | } 14 | 15 | public class TypedUserClient : TypedClient 16 | { 17 | public TypedUserClient(HttpClient client) : base(client) 18 | { 19 | } 20 | } 21 | 22 | public class TypedClientClient : TypedClient 23 | { 24 | public TypedClientClient(HttpClient client) : base(client) 25 | { 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /access-token-management/samples/WebJarJwt/Views/Home/CallApi.cshtml: -------------------------------------------------------------------------------- 1 | 

API Response

2 | 3 |
@ViewBag.Json
-------------------------------------------------------------------------------- /access-token-management/samples/WebJarJwt/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewData["Title"] = "Home Page"; 3 | } 4 | 5 |

Call API as Client

6 | 7 | Extension method 8 | | 9 | HTTP client factory 10 | | 11 | HTTP client factory (typed) 12 | 13 | 14 | -------------------------------------------------------------------------------- /access-token-management/samples/WebJarJwt/Views/Home/Secure.cshtml: -------------------------------------------------------------------------------- 1 | @using Microsoft.AspNetCore.Authentication 2 | 3 |

Call API as User

4 | 5 | Manual 6 | | 7 | Extension method 8 | | 9 | HTTP client factory 10 | | 11 | HTTP client factory (typed) 12 | 13 |

Call API as Client

14 | 15 | Extension method 16 | | 17 | HTTP client factory 18 | | 19 | HTTP client factory (typed) 20 | 21 | 22 |

Claims

23 | 24 |
25 | @foreach (var claim in User.Claims) 26 | { 27 |
@claim.Type
28 |
@claim.Value
29 | } 30 |
31 | 32 |

Properties

33 | 34 |
35 | @foreach (var prop in (await Context!.AuthenticateAsync())!.Properties!.Items) 36 | { 37 |
@prop.Key
38 |
@prop.Value
39 | } 40 |
-------------------------------------------------------------------------------- /access-token-management/samples/WebJarJwt/Views/Shared/_ValidationScriptsPartial.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | -------------------------------------------------------------------------------- /access-token-management/samples/WebJarJwt/Views/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @using WebJarJwt 2 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 3 | -------------------------------------------------------------------------------- /access-token-management/samples/WebJarJwt/Views/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "_Layout"; 3 | } 4 | -------------------------------------------------------------------------------- /access-token-management/samples/WebJarJwt/WebJarJwt.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net9.0 5 | enable 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /access-token-management/samples/WebJarJwt/WebJarJwt.v3.ncrunchproject: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | LostReference 5 | 6 | 7 | -------------------------------------------------------------------------------- /access-token-management/samples/WebJarJwt/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DuendeSoftware/foss/4e49d6b9dca55d8b6746d24256c93cb301156346/access-token-management/samples/WebJarJwt/wwwroot/favicon.ico -------------------------------------------------------------------------------- /access-token-management/samples/WebJarJwt/wwwroot/js/site.js: -------------------------------------------------------------------------------- 1 | // Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification 2 | // for details on configuring this project to bundle and minify static web assets. 3 | 4 | // Write your JavaScript code. 5 | -------------------------------------------------------------------------------- /access-token-management/samples/WebJarJwt/wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) .NET Foundation. All rights reserved. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use 4 | these files except in compliance with the License. You may obtain a copy of the 5 | License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software distributed 10 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 11 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | specific language governing permissions and limitations under the License. 13 | -------------------------------------------------------------------------------- /access-token-management/samples/Worker/TypedClient.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | namespace WorkerService; 5 | 6 | public class TypedClient 7 | { 8 | private readonly HttpClient _client; 9 | 10 | public TypedClient(HttpClient client) => _client = client; 11 | 12 | public async Task CallApi() => await _client.GetStringAsync("test"); 13 | } 14 | -------------------------------------------------------------------------------- /access-token-management/samples/Worker/Worker.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net9.0 4 | enable 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /access-token-management/samples/Worker/Worker.v3.ncrunchproject: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | LostReference 5 | 6 | 7 | -------------------------------------------------------------------------------- /access-token-management/samples/WorkerDI/TypedClient.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | namespace WorkerService; 5 | 6 | public class TypedClient 7 | { 8 | private readonly HttpClient _client; 9 | 10 | public TypedClient(HttpClient client) => _client = client; 11 | 12 | public async Task CallApi() => await _client.GetStringAsync("test"); 13 | } 14 | -------------------------------------------------------------------------------- /access-token-management/samples/WorkerDI/WorkerDI.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | net9.0 4 | enable 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /access-token-management/samples/WorkerDI/WorkerDI.v3.ncrunchproject: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | LostReference 5 | 6 | 7 | -------------------------------------------------------------------------------- /access-token-management/src/AccessTokenManagement.OpenIdConnect/AccessTokenManagement.OpenIdConnect.v3.ncrunchproject: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | LostReference 5 | 6 | 7 | -------------------------------------------------------------------------------- /access-token-management/src/AccessTokenManagement.OpenIdConnect/GlobalAliasses.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | global using CT = System.Threading.CancellationToken; 5 | 6 | -------------------------------------------------------------------------------- /access-token-management/src/AccessTokenManagement.OpenIdConnect/IOpenIdConnectConfigurationService.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | 5 | 6 | namespace Duende.AccessTokenManagement.OpenIdConnect; 7 | 8 | /// 9 | /// Service to extract necessary configuration from an OIDC handler 10 | /// 11 | public interface IOpenIdConnectConfigurationService 12 | { 13 | /// 14 | /// Reads the configuration from either the default challenge scheme or a named scheme 15 | /// 16 | /// 17 | /// 18 | /// 19 | public Task GetOpenIdConnectConfigurationAsync( 20 | Scheme? schemeName = null, 21 | CT ct = default); 22 | } 23 | -------------------------------------------------------------------------------- /access-token-management/src/AccessTokenManagement.OpenIdConnect/IPrincipalAccessor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | using System.Security.Claims; 5 | 6 | namespace Duende.AccessTokenManagement.OpenIdConnect; 7 | 8 | /// 9 | /// Service that retrieves the current principal. 10 | /// 11 | public interface IUserAccessor 12 | { 13 | /// 14 | /// Gets the current user. 15 | /// 16 | Task GetCurrentUserAsync(CT ct = default); 17 | } 18 | -------------------------------------------------------------------------------- /access-token-management/src/AccessTokenManagement.OpenIdConnect/IUserTokenRequestConcurrencyControl.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | 5 | 6 | namespace Duende.AccessTokenManagement.OpenIdConnect; 7 | 8 | /// 9 | /// Service to provide synchronization to token endpoint requests 10 | /// 11 | public interface IUserTokenRequestConcurrencyControl 12 | { 13 | /// 14 | /// Method to perform synchronization of work. 15 | /// 16 | public Task> ExecuteWithConcurrencyControlAsync(UserRefreshToken key, Func>> tokenRetriever, CT ct = default); 17 | } 18 | -------------------------------------------------------------------------------- /access-token-management/src/AccessTokenManagement.OpenIdConnect/Internal/CircuitServicesAccessor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | namespace Duende.AccessTokenManagement.OpenIdConnect.Internal; 5 | 6 | /// 7 | /// Provides access to scoped blazor services from non-blazor DI scopes, such as 8 | /// scopes created using IHttpClientFactory. 9 | /// 10 | internal class CircuitServicesAccessor 11 | { 12 | static readonly AsyncLocal BlazorServices = new(); 13 | 14 | internal IServiceProvider? Services 15 | { 16 | get => BlazorServices.Value; 17 | set => BlazorServices.Value = value!; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /access-token-management/src/AccessTokenManagement.OpenIdConnect/Internal/CircuitServicesServiceCollectionExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | using Microsoft.AspNetCore.Components.Server.Circuits; 5 | using Microsoft.Extensions.DependencyInjection; 6 | 7 | namespace Duende.AccessTokenManagement.OpenIdConnect.Internal; 8 | 9 | // This code is from the blazor documentation: 10 | // https://learn.microsoft.com/en-us/aspnet/core/blazor/fundamentals/dependency-injection?view=aspnetcore-8.0#access-server-side-blazor-services-from-a-different-di-scope 11 | 12 | internal static class CircuitServicesServiceCollectionExtensions 13 | { 14 | public static IServiceCollection AddCircuitServicesAccessor( 15 | this IServiceCollection services) 16 | { 17 | services.AddScoped(); 18 | services.AddScoped(); 19 | 20 | return services; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /access-token-management/src/AccessTokenManagement.OpenIdConnect/Internal/HttpContextUserAccessor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | using System.Security.Claims; 5 | using Microsoft.AspNetCore.Http; 6 | 7 | namespace Duende.AccessTokenManagement.OpenIdConnect.Internal; 8 | 9 | /// 10 | /// Accesses the current principal based on the HttpContext.User. 11 | /// 12 | internal class HttpContextUserAccessor : IUserAccessor 13 | { 14 | private readonly IHttpContextAccessor _httpContextAccessor; 15 | 16 | /// 17 | /// ctor 18 | /// 19 | public HttpContextUserAccessor(IHttpContextAccessor httpContextAccessor) => _httpContextAccessor = httpContextAccessor; 20 | 21 | /// 22 | public Task GetCurrentUserAsync(CT ct = default) => Task.FromResult(_httpContextAccessor.HttpContext?.User ?? new ClaimsPrincipal()); 23 | } 24 | -------------------------------------------------------------------------------- /access-token-management/src/AccessTokenManagement.OpenIdConnect/Internal/ServicesAccessorCircuitHandler.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | using Microsoft.AspNetCore.Components.Server.Circuits; 5 | 6 | namespace Duende.AccessTokenManagement.OpenIdConnect.Internal; 7 | 8 | internal class ServicesAccessorCircuitHandler( 9 | IServiceProvider services, 10 | CircuitServicesAccessor servicesAccessor) 11 | : CircuitHandler 12 | { 13 | public override Func CreateInboundActivityHandler( 14 | Func next) => 15 | async context => 16 | { 17 | servicesAccessor.Services = services; 18 | await next(context); 19 | servicesAccessor.Services = null; 20 | }; 21 | } 22 | -------------------------------------------------------------------------------- /access-token-management/src/AccessTokenManagement.OpenIdConnect/Internal/TokenNames.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | namespace Duende.AccessTokenManagement.OpenIdConnect.Internal; 5 | 6 | record TokenNames( 7 | string Token, 8 | string TokenType, 9 | string DPoPKey, 10 | string Expires, 11 | string RefreshToken, 12 | string IdentityToken, 13 | string ClientId); 14 | -------------------------------------------------------------------------------- /access-token-management/src/AccessTokenManagement.OpenIdConnect/OpenIdConnectTokenManagementDefaults.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | namespace Duende.AccessTokenManagement.OpenIdConnect; 5 | 6 | /// 7 | /// Default values 8 | /// 9 | public static class OpenIdConnectTokenManagementDefaults 10 | { 11 | /// 12 | /// Prefix to use for registering scheme based client credentials client in options system on the fly 13 | /// 14 | public const string ClientCredentialsClientNamePrefix = "Duende.TokenManagement.SchemeBasedClient:"; 15 | 16 | public static ClientCredentialsClientName ToClientName(this Scheme scheme) => 17 | ClientCredentialsClientName.Parse(ClientCredentialsClientNamePrefix + scheme); 18 | } 19 | -------------------------------------------------------------------------------- /access-token-management/src/AccessTokenManagement.OpenIdConnect/StringExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | using System.Diagnostics; 5 | using System.Diagnostics.CodeAnalysis; 6 | 7 | namespace Duende.AccessTokenManagement.OpenIdConnect; 8 | 9 | internal static class StringExtensions 10 | { 11 | [DebuggerStepThrough] 12 | public static bool IsMissing([NotNullWhen(false)] this string? value) => string.IsNullOrWhiteSpace(value); 13 | 14 | 15 | } 16 | -------------------------------------------------------------------------------- /access-token-management/src/AccessTokenManagement.OpenIdConnect/TransformPrincipalAfterRefreshAsync.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | using System.Security.Claims; 5 | 6 | namespace Duende.AccessTokenManagement.OpenIdConnect; 7 | 8 | /// 9 | /// Allows transforming the principal before re-issuing the authentication session 10 | /// 11 | /// 12 | /// 13 | /// 14 | 15 | public delegate Task TransformPrincipalAfterRefreshAsync(ClaimsPrincipal principal, CT ct); 16 | -------------------------------------------------------------------------------- /access-token-management/src/AccessTokenManagement.OpenIdConnect/UserRefreshToken.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | 5 | using Duende.AccessTokenManagement.DPoP; 6 | 7 | namespace Duende.AccessTokenManagement.OpenIdConnect; 8 | 9 | /// 10 | /// A record that captures the information to refresh an access token for a user. 11 | /// 12 | /// Minimally, you need a refresh token. If you use dpop, you'll also need the dpop proof key 13 | /// 14 | public sealed record UserRefreshToken(RefreshToken RefreshToken, DPoPProofKey? DPoPProofKey); 15 | -------------------------------------------------------------------------------- /access-token-management/src/AccessTokenManagement.OpenIdConnect/UserTokenRequestParameters.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | 5 | 6 | namespace Duende.AccessTokenManagement.OpenIdConnect; 7 | 8 | /// 9 | /// Additional optional per request parameters for a user access token request 10 | /// 11 | public sealed record UserTokenRequestParameters : TokenRequestParameters 12 | { 13 | /// 14 | /// Overrides the default sign-in scheme. This information may be used for state management. 15 | /// 16 | public Scheme? SignInScheme { get; set; } 17 | 18 | /// 19 | /// Overrides the default challenge scheme. This information may be used for deriving token service configuration. 20 | /// 21 | public Scheme? ChallengeScheme { get; set; } 22 | } 23 | -------------------------------------------------------------------------------- /access-token-management/src/AccessTokenManagement/AccessTokenManagement.v3.ncrunchproject: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | LostReference 5 | 6 | 7 | -------------------------------------------------------------------------------- /access-token-management/src/AccessTokenManagement/ClientCredentialsTokenManagementBuilder.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | using Microsoft.Extensions.DependencyInjection; 5 | 6 | namespace Duende.AccessTokenManagement; 7 | 8 | /// 9 | /// Builder for client credential clients 10 | /// 11 | public sealed class ClientCredentialsTokenManagementBuilder(IServiceCollection services) 12 | { 13 | public IServiceCollection Services { get; } = services; 14 | 15 | /// 16 | /// Adds a client credentials client to the token management system 17 | /// 18 | /// 19 | /// 20 | /// 21 | public ClientCredentialsTokenManagementBuilder AddClient(string name, 22 | Action configureOptions) 23 | { 24 | Services 25 | .Configure(name, configureOptions); 26 | 27 | return this; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /access-token-management/src/AccessTokenManagement/ClientCredentialsTokenManagementDefaults.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | namespace Duende.AccessTokenManagement; 5 | 6 | /// 7 | /// Default values 8 | /// 9 | public static class ClientCredentialsTokenManagementDefaults 10 | { 11 | /// 12 | /// Name of the back-channel HTTP client 13 | /// 14 | public const string BackChannelHttpClientName = "Duende.AccessTokenManagement.BackChannelHttpClient"; 15 | 16 | /// 17 | /// Name used to propagate access token parameters to HttpRequestMessage 18 | /// 19 | public const string TokenRequestParametersOptionsName = "Duende.AccessTokenManagement.AccessTokenParameters"; 20 | 21 | /// 22 | /// Name used to propagate additional claims to DPoP proof. The value is a dictionary of claims. 23 | /// 24 | public const string DPoPProofAdditionalPayloadClaims = 25 | "Duende.AccessTokenManagement.DPoPProofAdditionalPayloadClaims"; 26 | } 27 | -------------------------------------------------------------------------------- /access-token-management/src/AccessTokenManagement/DPoP/DPoPNonceContext.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | namespace Duende.AccessTokenManagement.DPoP; 5 | 6 | /// 7 | /// The context for a DPoP nonce. 8 | /// 9 | public sealed record DPoPNonceContext 10 | { 11 | /// 12 | /// The HTTP URL of the request 13 | /// 14 | public required Uri Url { get; set; } 15 | 16 | /// 17 | /// The HTTP method of the request 18 | /// 19 | public required HttpMethod Method { get; set; } 20 | } 21 | -------------------------------------------------------------------------------- /access-token-management/src/AccessTokenManagement/DPoP/IDPoPKeyStore.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | namespace Duende.AccessTokenManagement.DPoP; 5 | 6 | /// 7 | /// Service to access DPoP keys 8 | /// 9 | public interface IDPoPKeyStore 10 | { 11 | /// 12 | /// Gets the DPoP key for the client, or null if none available for the client 13 | /// 14 | Task GetKeyAsync(ClientCredentialsClientName clientName, 15 | CT ct = default); 16 | } 17 | -------------------------------------------------------------------------------- /access-token-management/src/AccessTokenManagement/DPoP/IDPoPNonceStore.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | namespace Duende.AccessTokenManagement.DPoP; 5 | 6 | /// 7 | /// Service to keep track of DPoP nonces 8 | /// 9 | public interface IDPoPNonceStore 10 | { 11 | /// 12 | /// Gets the nonce 13 | /// 14 | Task GetNonceAsync(DPoPNonceContext context, CT ct = default); 15 | 16 | /// 17 | /// Stores the nonce 18 | /// 19 | Task StoreNonceAsync(DPoPNonceContext context, DPoPNonce nonce, CT ct = default); 20 | } 21 | -------------------------------------------------------------------------------- /access-token-management/src/AccessTokenManagement/DPoP/IDPoPNonceStoreKeyGenerator.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | namespace Duende.AccessTokenManagement.DPoP; 5 | 6 | /// 7 | /// The logic to generate a key to store a DPoP nonce in the Cache 8 | /// 9 | public interface IDPoPNonceStoreKeyGenerator 10 | { 11 | /// 12 | /// Method to generate a cache key for a DPoP nonce 13 | /// 14 | /// 15 | /// 16 | string GenerateKey(DPoPNonceContext context); 17 | } 18 | -------------------------------------------------------------------------------- /access-token-management/src/AccessTokenManagement/DPoP/IDPoPProofService.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | namespace Duende.AccessTokenManagement.DPoP; 5 | 6 | /// 7 | /// Service to create DPoP proof tokens 8 | /// 9 | public interface IDPoPProofService 10 | { 11 | /// 12 | /// Serializes a requested model into a . 13 | /// 14 | Task CreateProofTokenAsync(DPoPProofRequest request, 15 | CT ct = default); 16 | 17 | /// 18 | /// Computes the thumbprint of the JSON web key. 19 | /// 20 | DPoPProofThumbprint? GetProofKeyThumbprint(DPoPProofKey dpopProofKey); 21 | } 22 | -------------------------------------------------------------------------------- /access-token-management/src/AccessTokenManagement/DPoP/Internal/DPoPErrors.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | using Duende.IdentityModel; 5 | 6 | namespace Duende.AccessTokenManagement.DPoP; 7 | 8 | internal static class DPoPErrors 9 | { 10 | private static readonly string[] DpopErrors = 11 | [ 12 | OidcConstants.TokenErrors.UseDPoPNonce, 13 | OidcConstants.TokenErrors.InvalidDPoPProof 14 | ]; 15 | 16 | public static bool IsDPoPError(string? message) 17 | { 18 | if (message == null) 19 | { 20 | return false; 21 | } 22 | 23 | return DpopErrors.Contains(message); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /access-token-management/src/AccessTokenManagement/DPoP/Internal/DPoPNonceStoreKeyGenerator.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | using Microsoft.Extensions.Options; 5 | 6 | namespace Duende.AccessTokenManagement.DPoP.Internal; 7 | 8 | /// 9 | /// The logic to generate a key to store a DPoP nonce in the cache. Defaults to 10 | /// + URL + Method. 11 | /// 12 | /// 13 | internal class DPoPNonceStoreKeyGenerator(IOptions options) 14 | : IDPoPNonceStoreKeyGenerator 15 | { 16 | public string GenerateKey(DPoPNonceContext context) => 17 | $"{options.Value.NonceStoreKeyPrefix}:{context.Url}:{context.Method}"; 18 | } 19 | -------------------------------------------------------------------------------- /access-token-management/src/AccessTokenManagement/DPoP/Internal/DefaultDPoPKeyStore.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | using Microsoft.Extensions.Options; 5 | 6 | namespace Duende.AccessTokenManagement.DPoP.Internal; 7 | 8 | /// 9 | /// Default implementation, which reads the dpop key from the client configuration. 10 | /// 11 | internal class DefaultDPoPKeyStore(IOptionsMonitor options) : IDPoPKeyStore 12 | { 13 | /// 14 | public virtual Task GetKeyAsync(ClientCredentialsClientName clientName, 15 | CT ct = default) 16 | { 17 | var client = options.Get(clientName.ToString()); 18 | 19 | 20 | if (client.DPoPJsonWebKey == null) 21 | { 22 | return Task.FromResult(null); 23 | } 24 | 25 | return Task.FromResult(client.DPoPJsonWebKey); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /access-token-management/src/AccessTokenManagement/FailedResult.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | namespace Duende.AccessTokenManagement; 5 | 6 | public sealed record FailedResult(string Error, string? ErrorDescription = null) : TokenResult 7 | { 8 | public override string ToString() 9 | { 10 | var description = string.IsNullOrEmpty(ErrorDescription) ? string.Empty : $" with description {ErrorDescription}"; 11 | return $"Failed to retrieve access token due to {Error}{description}."; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /access-token-management/src/AccessTokenManagement/ForceTokenRenewal.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | namespace Duende.AccessTokenManagement; 5 | 6 | public readonly record struct ForceTokenRenewal(bool Value); 7 | -------------------------------------------------------------------------------- /access-token-management/src/AccessTokenManagement/GlobalAliasses.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | global using CT = System.Threading.CancellationToken; 5 | 6 | -------------------------------------------------------------------------------- /access-token-management/src/AccessTokenManagement/IClientAssertionService.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | using Duende.IdentityModel.Client; 5 | 6 | namespace Duende.AccessTokenManagement; 7 | 8 | /// 9 | /// Service to create client assertions for back-channel clients 10 | /// 11 | public interface IClientAssertionService 12 | { 13 | /// 14 | /// Creates a client assertion based on client or configuration scheme (if present) 15 | /// 16 | /// 17 | /// 18 | /// 19 | /// 20 | Task GetClientAssertionAsync( 21 | ClientCredentialsClientName? clientName = null, 22 | TokenRequestParameters? parameters = null, 23 | CT ct = default); 24 | } 25 | -------------------------------------------------------------------------------- /access-token-management/src/AccessTokenManagement/IClientCredentialsCacheKeyGenerator.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | namespace Duende.AccessTokenManagement; 5 | 6 | /// 7 | /// The logic to generate a cache key. 8 | /// 9 | public interface IClientCredentialsCacheKeyGenerator 10 | { 11 | /// 12 | /// Method to generate a cache key for a client credentials token request 13 | /// 14 | /// The name of the client 15 | /// The parameters 16 | /// 17 | ClientCredentialsCacheKey GenerateKey( 18 | ClientCredentialsClientName clientName, 19 | TokenRequestParameters? parameters = null); 20 | } 21 | -------------------------------------------------------------------------------- /access-token-management/src/AccessTokenManagement/IClientCredentialsTokenEndpoint.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | namespace Duende.AccessTokenManagement; 5 | 6 | /// 7 | /// Abstraction for token endpoint operations 8 | /// 9 | public interface IClientCredentialsTokenEndpoint 10 | { 11 | /// 12 | /// Requests a client credentials access token. 13 | /// 14 | /// 15 | /// 16 | /// 17 | /// 18 | Task> RequestAccessTokenAsync( 19 | ClientCredentialsClientName clientName, 20 | TokenRequestParameters? parameters = null, 21 | CT ct = default); 22 | } 23 | -------------------------------------------------------------------------------- /access-token-management/src/AccessTokenManagement/IClientCredentialsTokenManager.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | namespace Duende.AccessTokenManagement; 5 | 6 | public interface IClientCredentialsTokenManager 7 | { 8 | Task> GetAccessTokenAsync( 9 | ClientCredentialsClientName clientName, 10 | TokenRequestParameters? parameters = null, 11 | CT ct = default); 12 | 13 | Task DeleteAccessTokenAsync(ClientCredentialsClientName clientName, 14 | TokenRequestParameters? parameters = null, 15 | CT ct = default); 16 | } 17 | -------------------------------------------------------------------------------- /access-token-management/src/AccessTokenManagement/Internal/Crypto.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | using System.Security.Cryptography; 5 | using System.Text; 6 | using Duende.IdentityModel; 7 | 8 | namespace Duende.AccessTokenManagement.Internal; 9 | 10 | internal static class Crypto 11 | { 12 | /// 13 | /// Simple hashing algorithm that should only be used to obfuscate ephemeral data in a deterministic way 14 | /// in logs, not for storing passwords 15 | /// 16 | /// The data to hash 17 | /// Hash of the incoming data. 18 | public static string HashData(string data) 19 | { 20 | using var sha = SHA256.Create(); 21 | var hash = sha.ComputeHash(Encoding.ASCII.GetBytes(data)); 22 | 23 | var leftPart = new byte[16]; 24 | Array.Copy(hash, leftPart, 16); 25 | 26 | return Base64Url.Encode(leftPart); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /access-token-management/src/AccessTokenManagement/Internal/DuendeAccessTokenSerializationContext.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | using System.Text.Json.Serialization; 5 | 6 | namespace Duende.AccessTokenManagement.Internal; 7 | 8 | /// 9 | /// Serialization context used by the DPoP proof service and the client credential token cache. 10 | /// 11 | [JsonSerializable(typeof(HttpMethod))] 12 | [JsonSerializable(typeof(Uri))] 13 | [JsonSerializable(typeof(long))] 14 | [JsonSerializable(typeof(Dictionary))] 15 | internal partial class DuendeAccessTokenSerializationContext : JsonSerializerContext; 16 | -------------------------------------------------------------------------------- /access-token-management/src/AccessTokenManagement/Internal/NoOpClientAssertionService.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | using Duende.IdentityModel.Client; 5 | 6 | namespace Duende.AccessTokenManagement.Internal; 7 | 8 | /// 9 | /// By default, we don't do client assertions. 10 | /// 11 | internal class NoOpClientAssertionService : IClientAssertionService 12 | { 13 | /// 14 | public Task GetClientAssertionAsync(ClientCredentialsClientName? clientName = null, 15 | TokenRequestParameters? parameters = null, 16 | CT ct = default) => 17 | Task.FromResult(null); 18 | } 19 | -------------------------------------------------------------------------------- /access-token-management/src/AccessTokenManagement/Internal/StringValueJsonConverter.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | using System.Text.Json; 5 | using System.Text.Json.Serialization; 6 | 7 | namespace Duende.AccessTokenManagement.Internal; 8 | 9 | internal class StringValueJsonConverter : JsonConverter where TSelf : struct, IStronglyTypedValue 10 | { 11 | public override TSelf Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) 12 | { 13 | var value = reader.GetString(); 14 | return value == null 15 | ? default 16 | : TSelf.Parse(value); 17 | } 18 | 19 | public override void Write(Utf8JsonWriter writer, TSelf value, JsonSerializerOptions options) => writer.WriteStringValue(value.ToString()); 20 | } 21 | -------------------------------------------------------------------------------- /access-token-management/src/AccessTokenManagement/Internal/ValidationRule.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | namespace Duende.AccessTokenManagement.Internal; 5 | 6 | internal delegate bool ValidationRule(T value, out string message); 7 | -------------------------------------------------------------------------------- /access-token-management/src/AccessTokenManagement/OTel/ActivitySources.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | using System.Diagnostics; 5 | 6 | namespace Duende.AccessTokenManagement.OTel; 7 | public static class ActivitySources 8 | { 9 | 10 | public static ActivitySource Main = new(ActivitySourceNames.Main); 11 | } 12 | 13 | public static class ActivitySourceNames 14 | { 15 | public static readonly string Main = typeof(ActivitySources).Assembly.GetName().Name!; 16 | } 17 | 18 | public static class ActivityNames 19 | { 20 | public const string AcquiringToken = "Duende.AccessTokenManagement.AcquiringToken"; 21 | } 22 | -------------------------------------------------------------------------------- /access-token-management/src/AccessTokenManagement/ServiceProviderKeys.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | namespace Duende.AccessTokenManagement; 5 | 6 | /// 7 | /// Keys that are used to inject different implementations into a specific service. 8 | /// 9 | public static class ServiceProviderKeys 10 | { 11 | /// 12 | /// Key for the client credentials token cache. Use this to inject a different cache implementation into the client credentials token cache. 13 | /// 14 | public const string ClientCredentialsTokenCache = "ClientCredentialsTokenCache"; 15 | 16 | /// 17 | /// Key for the DPoP nonce store. Use this to inject a different cache into the DPoP nonce store. 18 | /// 19 | public const string DPoPNonceStore = "DPoPNonceStore"; 20 | } 21 | -------------------------------------------------------------------------------- /access-token-management/src/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | atm- 8 | 3.0 9 | OAuth 2.0;OpenID Connect;Security;BFF;IdentityServer;ASP.NET Core;SPA;Blazor;Token Management 10 | 11 | 12 | -------------------------------------------------------------------------------- /access-token-management/test/AccessTokenManagement.Tests/AccessTokenHandler/Helpers/FakeHttpContextAccessor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | using Microsoft.AspNetCore.Http; 5 | 6 | namespace Duende.AccessTokenManagement.AccessTokenHandlers.Helpers; 7 | 8 | internal class FakeHttpContextAccessor : IHttpContextAccessor 9 | { 10 | public HttpContext? HttpContext { get; set; } 11 | } 12 | -------------------------------------------------------------------------------- /access-token-management/test/AccessTokenManagement.Tests/AccessTokenHandler/Helpers/TestAccessTokens.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | using Duende.AccessTokenManagement.DPoP; 5 | using Duende.AccessTokenManagement.OpenIdConnect; 6 | 7 | 8 | namespace Duende.AccessTokenManagement.AccessTokenHandlers.Helpers; 9 | 10 | public class TestAccessTokens(DPoPProofKey? dPoPJsonWebKey) 11 | { 12 | public UserToken UserToken = 13 | new UserToken() 14 | { 15 | ClientId = ClientId.Parse("clientId"), 16 | IdentityToken = IdentityToken.Parse("identity_token"), 17 | AccessToken = AccessToken.Parse("access_token_1"), 18 | AccessTokenType = AccessTokenType.Parse("Bearer"), 19 | Expiration = DateTimeOffset.UtcNow.AddMinutes(5), 20 | RefreshToken = RefreshToken.Parse("refresh_token"), 21 | DPoPJsonWebKey = dPoPJsonWebKey 22 | }; 23 | } 24 | -------------------------------------------------------------------------------- /access-token-management/test/AccessTokenManagement.Tests/AccessTokenManagement.Tests.net8.0.v3.ncrunchproject: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | AspNetTestHostCompatibility 5 | LostReference 6 | 7 | 8 | -------------------------------------------------------------------------------- /access-token-management/test/AccessTokenManagement.Tests/AccessTokenManagement.Tests.net9.0.v3.ncrunchproject: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | AspNetTestHostCompatibility 5 | LostReference 6 | 7 | 8 | -------------------------------------------------------------------------------- /access-token-management/test/AccessTokenManagement.Tests/AccessTokenManagement.Tests.v3.ncrunchproject: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | AspNetTestHostCompatibility 5 | LostReference 6 | 7 | 8 | -------------------------------------------------------------------------------- /access-token-management/test/AccessTokenManagement.Tests/DPoPExtensionTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | using Duende.AccessTokenManagement.DPoP; 5 | 6 | namespace Duende.AccessTokenManagement.Tests; 7 | 8 | public class DPoPExtensionTests 9 | { 10 | [Theory] 11 | [InlineData("DPoP-Nonce")] 12 | [InlineData("dpop-nonce")] 13 | [InlineData("DPOP-NONCE")] 14 | public void GetDPoPNonceIsCaseInsensitive(string headerName) 15 | { 16 | var expected = "expected-server-nonce"; 17 | var message = new HttpResponseMessage() 18 | { 19 | Headers = 20 | { 21 | { headerName, expected } 22 | } 23 | }; 24 | message.GetDPoPNonce().ShouldNotBeNull() 25 | .ToString().ShouldBe(expected); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /access-token-management/test/AccessTokenManagement.Tests/Framework/FakeTimeProvider.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | namespace Duende.AccessTokenManagement.Framework; 5 | internal class FakeTimeProvider(Func utcNow) : TimeProvider 6 | { 7 | public override DateTimeOffset GetUtcNow() => utcNow(); 8 | } 9 | -------------------------------------------------------------------------------- /access-token-management/test/AccessTokenManagement.Tests/Framework/TestClientAssertionService.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | 5 | using Duende.IdentityModel.Client; 6 | 7 | namespace Duende.AccessTokenManagement.Tests; 8 | 9 | public class TestClientAssertionService(string name, string assertionType, string assertionValue) 10 | : IClientAssertionService 11 | { 12 | public Task GetClientAssertionAsync(ClientCredentialsClientName? clientName = null, TokenRequestParameters? parameters = null, CancellationToken ct = default) 13 | { 14 | if (clientName == name) 15 | { 16 | return Task.FromResult(new() 17 | { 18 | Type = assertionType, 19 | Value = assertionValue 20 | }); 21 | } 22 | 23 | return Task.FromResult(null); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /access-token-management/test/AccessTokenManagement.Tests/Framework/TestDPoPNonceStore.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | using Duende.AccessTokenManagement.DPoP; 5 | 6 | namespace Duende.AccessTokenManagement.Tests; 7 | 8 | public class TestDPoPNonceStore : IDPoPNonceStore 9 | { 10 | public Task GetNonceAsync(DPoPNonceContext context, CancellationToken cancellationToken = default) 11 | => Task.FromResult(null); 12 | 13 | public Task StoreNonceAsync(DPoPNonceContext context, DPoPNonce nonce, CancellationToken cancellationToken = default) => Task.CompletedTask; 14 | } 15 | -------------------------------------------------------------------------------- /access-token-management/test/AccessTokenManagement.Tests/Framework/TestDPoPProofService.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | using Duende.AccessTokenManagement.DPoP; 5 | 6 | 7 | namespace Duende.AccessTokenManagement.Tests; 8 | 9 | public class TestDPoPProofService : IDPoPProofService 10 | { 11 | public string? ProofToken { get; set; } 12 | public string? Nonce { get; set; } 13 | public bool AppendNonce { get; set; } 14 | 15 | public Task CreateProofTokenAsync(DPoPProofRequest request, 16 | CancellationToken cancellationToken = default) 17 | { 18 | if (ProofToken == null) 19 | { 20 | return Task.FromResult(null); 21 | } 22 | 23 | Nonce = request.DPoPNonce?.ToString(); 24 | return Task.FromResult(DPoPProof.Parse(ProofToken + Nonce)); 25 | } 26 | 27 | public DPoPProofThumbprint? GetProofKeyThumbprint(DPoPProofKey request) => null; 28 | } 29 | -------------------------------------------------------------------------------- /access-token-management/test/AccessTokenManagement.Tests/Framework/TestOptionsMonitor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | using Microsoft.Extensions.Options; 5 | 6 | namespace Duende.AccessTokenManagement.Tests; 7 | 8 | public class TestOptionsMonitor(TOptions? currentValue = null) : IOptionsMonitor 9 | where TOptions : class, new() 10 | { 11 | public TOptions CurrentValue { get; set; } = currentValue ?? new(); 12 | 13 | public TOptions Get(string? name) => CurrentValue; 14 | 15 | public IDisposable? OnChange(Action listener) => throw new NotImplementedException(); 16 | } 17 | -------------------------------------------------------------------------------- /access-token-management/test/AccessTokenManagement.Tests/Types/AccessTokenTypeTests.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | namespace Duende.AccessTokenManagement.Types; 5 | 6 | public class AccessTokenTypeTests 7 | { 8 | [Fact] 9 | public void Can_change_to_scheme() 10 | { 11 | var type = AccessTokenType.Parse("dpop"); 12 | var sceme1 = Scheme.Parse("dpop"); 13 | 14 | var scheme = type.ToScheme(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /access-token-management/test/AccessTokenManagement.Tests/Usings.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | global using Shouldly; 5 | global using Xunit; 6 | -------------------------------------------------------------------------------- /access-token-management/test/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /foss.sln.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | True 3 | True -------------------------------------------------------------------------------- /foss.slnx.v3.ncrunchsolution: -------------------------------------------------------------------------------- 1 |  2 | 3 | True 4 | True 5 | True 6 | True 7 | 8 | -------------------------------------------------------------------------------- /foss.v3.ncrunchsolution: -------------------------------------------------------------------------------- 1 |  2 | 3 | True 4 | True 5 | True 6 | True 7 | 8 | -------------------------------------------------------------------------------- /global.json: -------------------------------------------------------------------------------- 1 | { 2 | "sdk": { 3 | "version": "9.0.203", 4 | "rollForward": "latestMajor", 5 | "allowPrerelease": false 6 | } 7 | } -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DuendeSoftware/foss/4e49d6b9dca55d8b6746d24256c93cb301156346/icon.png -------------------------------------------------------------------------------- /identity-model-oidc-client/.config/dotnet-tools.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1, 3 | "isRoot": true, 4 | "tools": { 5 | "NuGetKeyVaultSignTool": { 6 | "version": "3.1.6", 7 | "commands": [ 8 | "NuGetKeyVaultSignTool" 9 | ] 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /identity-model-oidc-client/.gitignore: -------------------------------------------------------------------------------- 1 | # Files we create in some of the clients and samples 2 | # (real implementations would use secure OS storage) 3 | proofkey 4 | refresh_token 5 | -------------------------------------------------------------------------------- /identity-model-oidc-client/clients/ConsoleClientWithBrowser/ConsoleClientWithBrowser.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net9.0 5 | Exe 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /identity-model-oidc-client/clients/ConsoleClientWithBrowser/ConsoleClientWithBrowser.v3.ncrunchproject: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | LostReference 5 | 6 | 7 | -------------------------------------------------------------------------------- /identity-model-oidc-client/clients/ConsoleClientWithBrowserAndDPoP/ConsoleClientWithBrowserAndDPoP.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net9.0 5 | Exe 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /identity-model-oidc-client/clients/ConsoleClientWithBrowserAndDPoP/ConsoleClientWithBrowserAndDPoP.v3.ncrunchproject: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | LostReference 5 | 6 | 7 | -------------------------------------------------------------------------------- /identity-model-oidc-client/clients/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /identity-model-oidc-client/clients/ManualModeConsoleClient/ManualModeConsoleClient.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | net9.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /identity-model-oidc-client/clients/ManualModeConsoleClient/ManualModeConsoleClient.v3.ncrunchproject: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | LostReference 5 | 6 | 7 | -------------------------------------------------------------------------------- /identity-model-oidc-client/samples/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /identity-model-oidc-client/samples/HttpSysConsoleClient/ConsoleSystemBrowser.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HttpSysConsoleClient", "HttpSysConsoleClient\HttpSysConsoleClient.csproj", "{119839BA-14F2-4964-8887-961C5A99CCDD}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {119839BA-14F2-4964-8887-961C5A99CCDD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {119839BA-14F2-4964-8887-961C5A99CCDD}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {119839BA-14F2-4964-8887-961C5A99CCDD}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {119839BA-14F2-4964-8887-961C5A99CCDD}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /identity-model-oidc-client/samples/HttpSysConsoleClient/HttpSysConsoleClient/HttpSysConsoleClient.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | net9.0 6 | enable 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /identity-model-oidc-client/samples/Maui/MauiApp1/MauiApp1/App.xaml: -------------------------------------------------------------------------------- 1 |  2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /identity-model-oidc-client/samples/Maui/MauiApp1/MauiApp1/App.xaml.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | namespace MauiApp1; 5 | 6 | public partial class App : Application 7 | { 8 | public App() 9 | { 10 | InitializeComponent(); 11 | 12 | MainPage = new AppShell(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /identity-model-oidc-client/samples/Maui/MauiApp1/MauiApp1/AppShell.xaml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /identity-model-oidc-client/samples/Maui/MauiApp1/MauiApp1/AppShell.xaml.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Duende Software. All rights reserved. 2 | // Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information. 3 | 4 | namespace MauiApp1; 5 | 6 | public partial class AppShell : Shell 7 | { 8 | public AppShell() 9 | { 10 | InitializeComponent(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /identity-model-oidc-client/samples/Maui/MauiApp1/MauiApp1/MainPage.xaml: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | 10 | 11 |