{"id":43208913,"url":"https://github.com/goodtocode/aspect-securedhttpclient","last_synced_at":"2026-02-01T07:13:06.703Z","repository":{"id":333795257,"uuid":"1138063285","full_name":"goodtocode/aspect-securedhttpclient","owner":"goodtocode","description":null,"archived":false,"fork":false,"pushed_at":"2026-01-21T05:55:44.000Z","size":42,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-21T14:40:08.621Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/goodtocode.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-20T07:40:39.000Z","updated_at":"2026-01-21T05:55:44.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/goodtocode/aspect-securedhttpclient","commit_stats":null,"previous_names":["goodtocode/aspect-securedhttpclient"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/goodtocode/aspect-securedhttpclient","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/goodtocode%2Faspect-securedhttpclient","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/goodtocode%2Faspect-securedhttpclient/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/goodtocode%2Faspect-securedhttpclient/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/goodtocode%2Faspect-securedhttpclient/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/goodtocode","download_url":"https://codeload.github.com/goodtocode/aspect-securedhttpclient/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/goodtocode%2Faspect-securedhttpclient/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28971713,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-01T06:46:42.625Z","status":"ssl_error","status_checked_at":"2026-02-01T06:44:56.173Z","response_time":56,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":[],"created_at":"2026-02-01T07:13:05.755Z","updated_at":"2026-02-01T07:13:06.695Z","avatar_url":"https://github.com/goodtocode.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Goodtocode.SecuredHttpClient\n\n[![NuGet CI/CD](https://github.com/goodtocode/aspect-securedhttpclient/actions/workflows/gtc-securedhttpclient-nuget.yml/badge.svg)](https://github.com/goodtocode/aspect-securedhttpclient/actions/workflows/gtc-securedhttpclient-nuget.yml)\n\nA secure, resilient HTTP client registration and access token management library for .NET and Blazor. Easily add OAuth2-protected HttpClients to your application with support for both Client Credentials and Authorization Code PKCE flows.\n\n## Features\n- Register HttpClients that automatically acquire and attach OAuth2 access tokens\n- Supports Client Credentials and Authorization Code PKCE flows\n- Built-in token caching and refresh\n- Pluggable token providers via `IAccessTokenProvider`\n- Resilience (retry with jitter) for HTTP requests\n- Extension methods for adding bearer tokens to requests\n- Simple integration with Blazor, ASP.NET Core, and .NET DI\n\n## Installation\nInstall via NuGet:\n\n```\ndotnet add package Goodtocode.SecuredHttpClient\n```\n\n## Quick Start\n\n### 1. Register a Secured HttpClient (Blazor/ASP.NET Core)\n\n#### Client Credentials Flow\n```csharp\nservices.AddClientCredentialHttpClient(\n    configuration, // IConfiguration\n    clientName: \"MyApiClient\",\n    baseAddress: new Uri(\"https://api.example.com\"),\n    maxRetry: 5 // optional\n);\n```\n\n#### Authorization Code PKCE Flow\n```csharp\nservices.AddAuthCodePkceHttpClient(\n    configuration, // IConfiguration\n    clientName: \"MyApiClient\",\n    baseAddress: new Uri(\"https://api.example.com\"),\n    maxRetry: 5 // optional\n);\n```\n\n#### Custom Registration for Blazor RCL\n```csharp\npublic static IServiceCollection AddAccessTokenHttpClient(\n    this IServiceCollection services,\n    Action\u003cResilientHttpClientOptions\u003e configureOptions)\n{\n    var options = new ResilientHttpClientOptions();\n    configureOptions(options);\n\n    if (options.BaseAddress == null)\n        throw new ArgumentNullException(nameof(configureOptions), \"BaseAddress must be provided.\");\n    if (string.IsNullOrWhiteSpace(options.ClientName))\n        throw new ArgumentNullException(nameof(configureOptions), \"ClientName must be provided.\");\n\n    services.AddOptions\u003cAuthCodePkceOptions\u003e()\n        .ValidateDataAnnotations()\n        .ValidateOnStart();\n    services.AddScoped\u003cIAccessTokenProvider, DownstreamApiAccessTokenProvider\u003e();\n    services.AddScoped\u003cTokenHandler\u003e();\n\n    services.AddHttpClient(options.ClientName, clientOptions =\u003e\n    {\n        clientOptions.DefaultRequestHeaders.Clear();\n        clientOptions.BaseAddress = options.BaseAddress;\n    })\n    .AddHttpMessageHandler\u003cTokenHandler\u003e()\n    .AddStandardResilienceHandler(resilienceOptions =\u003e\n    {\n        resilienceOptions.Retry.UseJitter = true;\n        resilienceOptions.Retry.MaxRetryAttempts = options.MaxRetry;\n    });\n\n    return services;\n}\n```\n\n### 2. Add Bearer Token to HttpClient (Manual)\n```csharp\nusing Goodtocode.SecuredHttpClient.Extensions;\n\nhttpClient.AddBearerToken(\"your-access-token\");\n```\n\n## Options\n- `ClientCredentialOptions`: For client credentials flow (ClientId, ClientSecret, TokenUrl, Scope)\n- `AuthCodePkceOptions`: For PKCE flow (ClientId, CodeVerifier, RedirectUri, TokenUrl, Scope)\n- `ResilientHttpClientOptions`: For base address, client name, and retry settings\n\n## How It Works\n- Token providers implement `IAccessTokenProvider` and handle token acquisition and caching\n- `TokenHandler` automatically attaches the access token to outgoing requests\n- Resilience is provided via retry policies with jitter\n\n## License\nMIT\n\n## Contact\n- [GitHub Repo](https://github.com/goodtocode/aspect-securedhttpclient)\n- [@goodtocode](https://twitter.com/goodtocode)\n\n## Version History\n\n| Version | Date       | Changes                       |\n|---------|------------|-------------------------------|\n| 1.1.0   | 2026-01-22 | Bump from .NET 9 to .NET 10   |","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgoodtocode%2Faspect-securedhttpclient","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgoodtocode%2Faspect-securedhttpclient","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgoodtocode%2Faspect-securedhttpclient/lists"}