Skip to content

SDK-2768-net-support-central-auth-tokens#555

Open
mehmet-yoti wants to merge 5 commits into
developmentfrom
SDK-2768-net-support-central-auth-tokens
Open

SDK-2768-net-support-central-auth-tokens#555
mehmet-yoti wants to merge 5 commits into
developmentfrom
SDK-2768-net-support-central-auth-tokens

Conversation

@mehmet-yoti

@mehmet-yoti mehmet-yoti commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add central auth (Bearer token) support alongside existing signed-request auth via a Strategy pattern (IAuthStrategy)
  • New BearerTokenAuthStrategy sends Authorization: Bearer <token>; existing SignedRequestAuthStrategy encapsulates RSA digest + nonce/timestamp
  • Both DigitalIdentityClient and DocScanClient gain new constructors accepting a bearer token string
  • New AuthenticationTokenGenerator issues PS384 JWT → OAuth2 client_credentials grant to obtain access tokens, with a fluent builder

Build() used Validation.NotNull(_keyPair, nameof(_keyPair)) which throws ArgumentNullException with the private field name exposed in the parameter. The test Build_MissingKeyPairShouldThrow expects InvalidOperationException, consistent with the rest of the builder's Build() validation pattern (missing sdkId and empty scopes both throw InvalidOperationException).

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces an authentication strategy abstraction (IAuthStrategy) to support both existing signed-request auth and new central-auth bearer token auth across the SDK, plus a central-auth token generator (JWT client assertion → OAuth2 client_credentials).

Changes:

  • Added IAuthStrategy with concrete implementations: SignedRequestAuthStrategy, BearerTokenAuthStrategy, and NoAuthStrategy.
  • Updated request construction and service/client APIs to accept an auth strategy (and added bearer-token factory methods for clients).
  • Added central-auth token generation via AuthenticationTokenGenerator + fluent AuthenticationTokenGeneratorBuilder, with accompanying tests.

Reviewed changes

Copilot reviewed 26 out of 27 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
test/Yoti.Auth.Tests/Web/SignedRequestAuthStrategyTests.cs New unit tests for signed-request strategy behavior and guards.
test/Yoti.Auth.Tests/Web/RequestBuilderTests.cs Updated tests for new auth-strategy path and mutual exclusion with keypair.
test/Yoti.Auth.Tests/Web/NoAuthStrategyTests.cs New tests for no-auth strategy semantics.
test/Yoti.Auth.Tests/Web/BearerTokenAuthStrategyTests.cs New tests for bearer token strategy headers and validation.
test/Yoti.Auth.Tests/DocScan/DocScanServiceTests.cs Updated Doc Scan service tests to use IAuthStrategy rather than sdkId/keyPair params.
test/Yoti.Auth.Tests/DocScan/DocScanClientTests.cs Added tests for DocScanClient.FromBearerToken(...).
test/Yoti.Auth.Tests/DigitalIdentityClientTests.cs Added tests for DigitalIdentityClient.FromBearerToken(...) and bearer-token limitations.
test/Yoti.Auth.Tests/DigitalIdentityClientEngineTests.cs Updated engine tests to pass IAuthStrategy.
test/Yoti.Auth.Tests/DigitalIdentity/DigitalIdentityServiceTests.cs Updated Digital Identity service tests to use IAuthStrategy.
test/Yoti.Auth.Tests/CentralAuth/AuthenticationTokenGeneratorTests.cs New tests for OAuth token generation request/response handling.
test/Yoti.Auth.Tests/CentralAuth/AuthenticationTokenGeneratorBuilderTests.cs New tests for builder validation and configuration options.
src/Yoti.Auth/Web/SignedRequestAuthStrategy.cs New signed-request strategy encapsulating digest + nonce/timestamp generation.
src/Yoti.Auth/Web/RequestBuilder.cs Added WithAuthStrategy, mutual exclusion checks, and strategy-driven query/header injection.
src/Yoti.Auth/Web/NoAuthStrategy.cs New no-auth strategy returning no headers/query params.
src/Yoti.Auth/Web/IAuthStrategy.cs New authentication strategy contract used by clients/services.
src/Yoti.Auth/Web/HeadersFactory.cs Added strategy-based header injection helper.
src/Yoti.Auth/Web/BearerTokenAuthStrategy.cs New bearer token strategy adding Authorization: Bearer <token>.
src/Yoti.Auth/DocScan/DocScanService.cs Refactored Doc Scan service methods to accept IAuthStrategy and optionally include sdkId.
src/Yoti.Auth/DocScan/DocScanClient.cs Client now uses IAuthStrategy; added bearer-token factory method.
src/Yoti.Auth/DigitalIdentityClientEngine.cs Engine methods updated to accept IAuthStrategy.
src/Yoti.Auth/DigitalIdentityClient.cs Client now uses IAuthStrategy; added bearer-token factory methods.
src/Yoti.Auth/DigitalIdentity/DigitalIdentityService.cs Service refactored to accept IAuthStrategy; added signed-request requirement for receipt decryption.
src/Yoti.Auth/Constants/Api.cs Added Authorization header constant and default auth API URL.
src/Yoti.Auth/CentralAuth/AuthenticationTokenResponse.cs New DTO for auth token endpoint responses.
src/Yoti.Auth/CentralAuth/AuthenticationTokenGeneratorBuilder.cs New builder for configuring AuthenticationTokenGenerator.
src/Yoti.Auth/CentralAuth/AuthenticationTokenGenerator.cs New implementation for JWT client assertion and token acquisition.
.gitignore Ignore generated coverage XML files.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +37 to +43
public AuthenticationTokenGeneratorBuilder WithScopes(IEnumerable<string> scopes)
{
if (scopes == null)
throw new ArgumentNullException(nameof(scopes));
_scopes.AddRange(scopes);
return this;
}
Comment thread src/Yoti.Auth/CentralAuth/AuthenticationTokenGeneratorBuilder.cs
Comment on lines +27 to +31
public async Task<AuthenticationTokenResponse> GetToken(HttpClient httpClient)
{
string jwt = BuildJwt();
string scope = string.Join(" ", _scopes);

Comment thread src/Yoti.Auth/Web/BearerTokenAuthStrategy.cs
Comment on lines 99 to 102
Validation.NotNull(httpClient, nameof(httpClient));
Validation.NotNull(apiUrl, nameof(apiUrl));
Validation.NotNull(sdkId, nameof(sdkId));
Validation.NotNull(keyPair, nameof(keyPair));
Validation.NotNull(authStrategy, nameof(authStrategy));

Comment thread src/Yoti.Auth/Web/RequestBuilder.cs Outdated
Comment on lines +321 to +322
string result = endpointBuilder.ToString().TrimEnd('&').TrimEnd('?');
return result.EndsWith("?", StringComparison.Ordinal) ? result.TrimEnd('?') : result;
… code

- WithScopes: validate each scope entry for null/whitespace before adding to avoid invalid OAuth scope strings
- WithScope: validate the scope argument before adding
- AuthenticationTokenGenerator.GetToken: add null check for httpClient to give a clear exception instead of NullReferenceException from PostAsync
- BearerTokenAuthStrategy: upgrade IsNullOrEmpty to IsNullOrWhiteSpace to reject whitespace-only tokens that would produce an invalid Authorization header
- DigitalIdentityService.CreateQrCode: add explicit validation for sessionId and qrRequestPayload to prevent malformed endpoints and serializing null to "null"
- RequestBuilder: remove redundant EndsWith("?") check after TrimEnd('?') — the condition can never be true; simplify to a single TrimEnd chain
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants