Interface ISameDeviceSessionStore
- Namespace
- Tessio.Verifier.AspNetCore
- Assembly
- Tessio.Verifier.AspNetCore.dll
An ISessionStore that can run the same-device flow: a session bound to the browser that started it, whose verified presentation is held until that browser comes back with the response code the wallet's redirect carried. Everything about binding, holding and redeeming belongs here.
public interface ISameDeviceSessionStore : IStateCorrelatingSessionStore, ISessionStore
- Inherited Members
Remarks
SPEC: HAIP 1.0 section 5.1, "Verifiers and Wallets MUST support the "same-device" flow", and for it "Verifiers MUST reject presentations if Wallets do not follow the redirect back or the redirect back arrives in a different user session to the one the request was initiated in". OpenID4VP 1.0 section 14.2: the Response URI "MUST include a fresh secret (Response Code) into the redirect URI returned to the Wallet and the Verifier's Response URI MUST require the frontend to pass the respective Response Code when fetching the Authorization Response". The library gates completing the session on the code and the binding together, rather than gating the fetch of its result.
A separate interface because ISessionStore is frozen, so a store written against
contracts-v0 keeps compiling. MapTessioVerifier maps the same-device routes only when the
registered store implements this, and logs a warning when it does not. The built-in
InMemorySessionStore implements it.
The values passed in are SHA-256 hashes, never the secrets themselves, so a store's contents do not let anyone redeem a presentation. Compare them with FixedTimeEquals(ReadOnlySpan<byte>, ReadOnlySpan<byte>).
Methods
CreateBoundAsync(PresentationRequestOptions, byte[], CancellationToken)
Creates a session, as CreateAsync(PresentationRequestOptions, CancellationToken) does, bound to the browser whose
binding hash is browserBinding.
Task<VerificationSession> CreateBoundAsync(PresentationRequestOptions options, byte[] browserBinding, CancellationToken ct = default)
Parameters
optionsPresentationRequestOptionsbrowserBindingbyte[]ctCancellationToken
Returns
HoldAsync(string, VerificationResult, byte[], DateTimeOffset, CancellationToken)
Holds a verified result for a bound session until redeemBy,
leaving the session Pending. The callback asks this for every
verified presentation, cross-device ones included, because the binding is one of the two marks of a
same-device session.
Task<SameDeviceHold> HoldAsync(string sessionId, VerificationResult result, byte[] responseCodeHash, DateTimeOffset redeemBy, CancellationToken ct = default)
Parameters
sessionIdstringresultVerificationResultresponseCodeHashbyte[]redeemByDateTimeOffsetctCancellationToken
Returns
- Task<SameDeviceHold>
NotBound for a session the store holds no binding for, whatever its state, so that asking about a cross-device session changes nothing; NotPending when the session is unknown, or is bound and has ended or already holds an unexpired presentation.
Remarks
Only a verified presentation is held. A failing one that arrives while another is held is refused
under the usual rule, so without CompleteOnlyOnValidResponse it ends
the session and the held presentation with it. Only the holder of the request's state can
send one, and a session ended early is a refusal, never a wrong verdict.
RedeemAsync(string, byte[], byte[], CancellationToken)
Redeems the held presentation whose response code hashes to responseCodeHash.
When browserBinding matches the session's binding, completes the session with the
held result in the same step. When it does not, discards the held result and leaves the session pending
for the caller to reject. A browser that sent no cookie is passed a hash nothing was ever bound to.
Task<SameDeviceRedemption> RedeemAsync(string sessionId, byte[] responseCodeHash, byte[] browserBinding, CancellationToken ct = default)
Parameters
sessionIdstringresponseCodeHashbyte[]browserBindingbyte[]ctCancellationToken