{"id":20004909,"url":"https://github.com/hawxy/auth0net.dependencyinjection","last_synced_at":"2026-04-03T08:03:51.539Z","repository":{"id":43715492,"uuid":"313621671","full_name":"Hawxy/Auth0Net.DependencyInjection","owner":"Hawxy","description":"Dependency Injection, HttpClientFactory \u0026 ASP.NET Core extensions for Auth0.NET","archived":false,"fork":false,"pushed_at":"2025-05-12T14:35:33.000Z","size":207,"stargazers_count":48,"open_issues_count":0,"forks_count":1,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-06-18T21:43:42.086Z","etag":null,"topics":["asp","auth0","auth0-api","auth0-net","grpc","httpclient","httpclientfactory"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Hawxy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":"Hawxy"}},"created_at":"2020-11-17T13:04:04.000Z","updated_at":"2025-05-12T14:31:59.000Z","dependencies_parsed_at":"2024-01-21T10:21:33.043Z","dependency_job_id":"49289ad4-11c1-4ad3-9b7c-4d26a2ede5e0","html_url":"https://github.com/Hawxy/Auth0Net.DependencyInjection","commit_stats":null,"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"purl":"pkg:github/Hawxy/Auth0Net.DependencyInjection","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Hawxy%2FAuth0Net.DependencyInjection","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Hawxy%2FAuth0Net.DependencyInjection/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Hawxy%2FAuth0Net.DependencyInjection/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Hawxy%2FAuth0Net.DependencyInjection/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Hawxy","download_url":"https://codeload.github.com/Hawxy/Auth0Net.DependencyInjection/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Hawxy%2FAuth0Net.DependencyInjection/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261759160,"owners_count":23205507,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["asp","auth0","auth0-api","auth0-net","grpc","httpclient","httpclientfactory"],"created_at":"2024-11-13T05:37:04.933Z","updated_at":"2026-04-03T08:03:51.530Z","avatar_url":"https://github.com/Hawxy.png","language":"C#","funding_links":["https://github.com/sponsors/Hawxy"],"categories":[],"sub_categories":[],"readme":"# Auth0.NET Dependency Injection Extensions\n[![NuGet](https://img.shields.io/nuget/v/Auth0Net.DependencyInjection.svg?style=flat-square)](https://www.nuget.org/packages/Auth0Net.DependencyInjection)\n[![Nuget](https://img.shields.io/nuget/dt/Auth0Net.DependencyInjection?style=flat-square)](https://www.nuget.org/packages/Auth0Net.DependencyInjection)\n\n\u003ch1 align=\"center\"\u003e\n\u003cimg align=\"center\" src=\"https://user-images.githubusercontent.com/975824/128343470-8d97e39d-ff8a-4daf-8ebf-f9039a46abd6.png\" height=\"130px\" /\u003e\n\u003c/h1\u003e\n\nIntegrating [Auth0.NET](https://github.com/auth0/auth0.net) into your project whilst following idiomatic .NET conventions can be cumbersome and involve a sizable amount of boilerplate shared between projects. \n\nThis library hopes to solve that problem, featuring:\n\n :white_check_mark: Extensions for `Microsoft.Extensions.DependencyInjection`.\n \n :white_check_mark: Automatic access token caching \u0026 renewal for the Management API and your own REST \u0026 Grpc services\n \n :white_check_mark: [HttpClientFactory](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/http-requests) integration for centralized extensibility and management of the internal HTTP handlers.\n \n :white_check_mark: `IHttpClientBuilder` extensions, providing handlers to automatically append access tokens to outgoing requests.\n \n This library is compatible with .NET 8+ as well as .NET Framework 4.8 and is suitable for use in ASP.NET Core and standalone .NET Generic Host applications.\n \n ## Install\n \n Add `Auth0Net.DependencyInjection` to your project:\n \n ```\ndotnet add package Auth0Net.DependencyInjection\n```\n \n ## Scenarios\n \n ### Authentication Client Only\n \n![Auth0Authentication](https://user-images.githubusercontent.com/975824/128319560-4b859296-44f5-4219-a1b3-8255bf29f1b3.png)\n \nIf you're simply using the `AuthenticationApiClient` and nothing else, you can call `AddAuth0AuthenticationClient` and pass in your Auth0 Domain. This integration is lightweight and does not support any other features of this library. \n \n ```csharp\nservices.AddAuth0AuthenticationClient(\"your-auth0-domain.auth0.com\");\n```\n\nYou can then request the `IAuthenticationApiClient` within your class:\n\n```csharp\n\npublic class AuthController : ControllerBase\n{\n    private readonly IAuthenticationApiClient _authenticationApiClient;\n\n    public AuthController(IAuthenticationApiClient authenticationApiClient)\n    {\n        _authenticationApiClient = authenticationApiClient;\n    }\n ```\n\n### Authentication Client + Management Client \n \n![Auth0AuthenticationAndManagement](https://user-images.githubusercontent.com/975824/128319611-9083d473-191d-4593-ad0f-9669335dbb62.png)\n\n \nAdd the `AuthenticationApiClient` with `AddAuth0AuthenticationClient`, and provide a [machine-to-machine application](https://auth0.com/docs/applications/set-up-an-application/register-machine-to-machine-applications) configuration that will be consumed by the Management Client, Token Cache and IHttpClientBuilder integrations. This extension **must** be called before using any other extensions within this library:\n \n ```csharp\nservices.AddAuth0AuthenticationClient(config =\u003e\n{\n    config.Domain = builder.Configuration[\"Auth0:Domain\"];\n    config.ClientId = builder.Configuration[\"Auth0:ClientId\"];\n    config.ClientSecret = builder.Configuration[\"Auth0:ClientSecret\"];\n});\n```\n\nAdd the `ManagementApiClient` with `AddAuth0ManagementClient()`. The client will attach the Access Token automatically:\n\n```csharp\nservices.AddAuth0ManagementClient();\n```\n\nEnsure your Machine-to-Machine application is authorized to request tokens from the Managment API and it has the correct scopes for the features you wish to use.\n\nYou can then request the `IManagementApiClient` (or `IAuthenticationApiClient`) within your services:\n\n```csharp\npublic class MyAuth0Service : IAuth0Service\n{\n    private readonly IManagementApiClient _managementApiClient;\n\n    public MyAuth0Service(IManagementApiClient managementApiClient)\n    {\n        _managementApiClient = managementApiClient;\n    }\n ```\n \n \n#### Handling Custom Domains\n\nIf you're using a custom domain with your Auth0 tenant, and it's being specified when calling `AddAuth0AuthenticationClient`, you will run into a problem whereby the `audience` of the Management API is being incorrectly set. You can override this via the `Audience` property:\n\n```cs\nservices.AddAuth0ManagementClient(c =\u003e\n    {\n        // Set the audience to your default Auth0 domain.\n        c.Audience = \"my-tenant.au.auth0.com\";\n    });\n```\n\n### External HttpClient \u0026 Grpc Services (Machine-To-Machine Tokens)\n\n![Auth0AuthenticationAll](https://user-images.githubusercontent.com/975824/128319653-418e0e72-2ddf-4d02-9544-1d60bd523321.png)\n\n**Note:** This feature relies on `services.AddAuth0AuthenticationClient(config =\u003e ...)` being called and configured as outlined in the previous section. \n\nThis library includes a delegating handler - effectively middleware for your HttpClient - that will append an access token to all outbound requests. This is useful for calling other services that are protected by Auth0. This integration requires your service implementation to use `IHttpClientFactory` as part of its registration. You can read more about it [here](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/http-requests)\n\n#### HttpClient\nUse `AddAccessToken` along with the required audience:\n\n```csharp\nservices.AddHttpClient\u003cMyHttpService\u003e(x =\u003e x.BaseAddress = new Uri(builder.Configuration[\"MyHttpService:Url\"]))\n        .AddAccessToken(config =\u003e config.Audience = builder.Configuration[\"MyHttpService:Audience\"]);\n```\n\n#### Grpc\n\nThis extension is compatible with any registration that returns a `IHttpClientBuilder`, thus it can be used with [Grpc's client factory](https://docs.microsoft.com/en-us/aspnet/core/grpc/clientfactory):\n\n```csharp\nservices.AddGrpcClient\u003cUserService.UserServiceClient\u003e(x =\u003e x.Address = new Uri(builder.Configuration[\"MyGrpcService:Url\"]))\n        .AddAccessToken(config =\u003e config.Audience = builder.Configuration[\"MyGrpcService:Audience\"]);\n```\n\n#### Advanced\n\n`AddAccessToken` also has an option for passing in a func that can resolve the audience at runtime. This can be useful if your expected audiences always follow a pattern, or if you rely on service discovery, such as from [Steeltoe.NET](https://docs.steeltoe.io/api/v3/discovery/discovering-services.html):\n\n```csharp\nservices.AddHttpClient\u003cMyHttpService\u003e(x=\u003e x.BaseAddress = new Uri(\"https://MyServiceName/\"))\n        .AddServiceDiscovery()\n        .AddAccessToken(config =\u003e config.AudienceResolver = request =\u003e request.RequestUri.GetLeftPart(UriPartial.Authority));\n```\n\n### M2M Organizations Support\n\nThis library includes support for [Machine-to-Machine (M2M) Access for Organizations](https://auth0.com/docs/manage-users/organizations/organizations-for-m2m-applications), including static and dynamic scenarios.\nThis feature is important if your internal or third-party services expect a token to be scoped to a specific Auth0 organization.\n\nOrgs support must be enabled for your combination of client/api/org(s) before usage.\n\n#### Static Organization\n\nClients that simply require a single organization for a specific client can do so via setting the `Organization` property when configuring the access token:\n\n```csharp\nbuilder.Services\n    .AddGrpcClient\u003cUserService.UserServiceClient\u003e(x =\u003e x.Address = new Uri(builder.Configuration[\"MyApi:Url\"]!))\n    .AddAccessToken(config =\u003e\n    {\n        config.Audience = builder.Configuration[\"MyApi:Audience\"];\n        config.Organization = builder.Configuration[\"MyApi:Organization\"];\n    });\n```\n\n#### Dynamic Organization via Request Metadata\n\nIf you already include org metadata as part of your network request or via the request options and would like to easily migrate to Org-scoped tokens, you can choose to resolve the organization at runtime via the `OrganizationResolver`:\n\n```csharp\nbuilder.Services\n    .AddGrpcClient\u003cUserService.UserServiceClient\u003e(x =\u003e x.Address = new Uri(builder.Configuration[\"MyApi:Url\"]!))\n    .AddAccessToken(config =\u003e\n    {\n        config.Audience = builder.Configuration[\"MyApi:Audience\"];\n        config.OrganizationResolver = x =\u003e\n            x.Headers.TryGetValues(\"org-id\", out var values) \n                ? values.SingleOrDefault() \n                : null;\n    });\n```\n\n#### Dynamic Organization via Client Scope (Experimental)\n\nIf your organization source is scoped to the usage of your service, such as an ASP.NET Core request, then you'll want the ability to freely set the Organization.\nYou can achieve this by injecting your client via `OrganizationScopeFactory\u003cTClient\u003e` and then creating an organization scope via `.CreateScope`:\n\n```csharp\n// Inject the factory around your remote client\nprivate readonly OrganizationScopeFactory\u003cUsersService\u003e _scopeFactory;\n\npublic QueryUsersService(OrganizationScopeFactory\u003cUsersService\u003e scopeFactory)\n{\n    _scopeFactory = scopeFactory;\n}\n\npublic async Task CreateUserAsync(User user, string orgId)\n{\n    // Create the scope so the MTM token is generated with the current OrgId    \n    using var orgScope = _scopeFactory.CreateScope(orgId);\n    await orgScope.Client.CreateUser(user, stoppingToken);\n}\n  \n```\n\nALWAYS ensure you dispose of the scope when finished.\n\nThere's a few limitations if you're using this functionality, as it uses `AsyncLocal` internally:\n\n- Never use multiple client scopes at the same time, either with the same or different client types. This will throw an exception.\n- Never call any other client that utilizes `.AddAccessToken` within a client scope. This may cause the wrong Organization ID/Name being used for a given request.\n\nIf you have a use-case for either of these items, please open an issue with an example.\n\nThis functionality is marked as experimental, and you must `#pragma warning disable AUTH0_EXPERIMENTAL` to use it. \n\n## Additional Functionality\n\n### Utility \n\nThis library exposes a simple string extension, `ToHttpsUrl()`, that can be used to format the naked Auth0 domain sitting in your configuration into a proper URL.\n\nThis is identical to `https://{Configuration[\"Auth0:Domain\"]}/` that you usually end up writing _somewhere_ in your `Program.cs`.\n\nFor example, formatting the domain for the JWT Authority:\n\n```csharp\n.AddJwtBearer(options =\u003e\n             {\n                 // \"my-tenant.auth0.com\" -\u003e \"https://my-tenant.auth0.com/\"\n                 options.Authority = builder.Configuration[\"Auth0:Domain\"].ToHttpsUrl();\n                 //...\n             });\n ```\n\n## Internals\n\n### Client Lifetimes\n\nBoth the authentication and authorization clients are registered as singletons and are suitable for injection into any other lifetime.\n\n### Samples\n\nBoth a .NET Generic Host and ASP.NET Core examples are available in the [samples](https://github.com/Hawxy/Auth0Net.DependencyInjection/tree/main/samples) directory.\n\n### Internal Cache\n\nThe `Auth0TokenCache` will cache a token for a given audience until at least 95% of the expiry time. If a request to the cache is made between 95% and 99% of expiry, the token will be refreshed in the background before expiry is reached.\n\nAn additional 1% of lifetime is removed to protect against clock drift between distributed systems.\n\nIn some situations you might want to request an access token from Auth0 manually. You can achieve this by injecting `IAuth0TokenCache` into a class and calling `GetTokenAsync` with the audience of the API you're requesting the token for.\n\nAn in-memory-only instance of [FusionCache](https://github.com/ZiggyCreatures/FusionCache) is used as the caching implementation. This instance is _named_ and will not impact other usages of FusionCache. \n\nIf you want to use your own implementation of FusionCache, specify `FusionCacheInstance` when configurating the authentication client:\n\n```csharp\nservices.AddAuth0AuthenticationClient(x =\u003e\n {\n     //...\n     // Use the default FusionCache instance registered via `.AddFusionCache()`\n     x.FusionCacheInstance = FusionCacheOptions.DefaultCacheName\n });\n```\n\n## Disclaimer\n\nI am not affiliated with nor represent Auth0. All implementation issues regarding the underlying `ManagementApiClient` and `AuthenticationApiClient` should go to the official [Auth0.NET Respository](https://github.com/auth0/auth0.net).\n\n### License notices\n\nIcons used under the [MIT License](https://github.com/auth0/identicons/blob/master/LICENSE) from the [Identicons](https://github.com/auth0/identicons) pack.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhawxy%2Fauth0net.dependencyinjection","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhawxy%2Fauth0net.dependencyinjection","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhawxy%2Fauth0net.dependencyinjection/lists"}