| | | 1 | | using Google.Apis.Auth; |
| | | 2 | | |
| | | 3 | | namespace ArturRios.Heimdall.WebApi.Security; |
| | | 4 | | |
| | | 5 | | /// <summary> |
| | | 6 | | /// Builds the <see cref="GoogleJsonWebSignature.ValidationSettings" /> UC-25's verification runs |
| | | 7 | | /// under (NFR-13). |
| | | 8 | | /// </summary> |
| | | 9 | | /// <remarks> |
| | | 10 | | /// <para> |
| | | 11 | | /// Split out of <see cref="GoogleIdTokenVerifier" /> for the reason |
| | | 12 | | /// <see cref="GoogleIdTokenClaims" /> was: the verifier itself calls the static, |
| | | 13 | | /// network-bound |
| | | 14 | | /// <see cref="GoogleJsonWebSignature.ValidateAsync(string, GoogleJsonWebSignature.ValidationSettings)" />, |
| | | 15 | | /// which offers no seam, and reaching it in a test would mean contacting Google or holding |
| | | 16 | | /// Google's signing key. What is left here is a pure function of the configured options, so |
| | | 17 | | /// <c>GoogleIdTokenValidationSettingsTests</c> can pin it. |
| | | 18 | | /// </para> |
| | | 19 | | /// <para> |
| | | 20 | | /// Which matters more than it looks. Of the four checks NFR-13 names — signature, issuer, |
| | | 21 | | /// audience, expiry — three are Google's library's to make and are not ours to get wrong. |
| | | 22 | | /// The audience is the one this application supplies, and it is the one that decides whether |
| | | 23 | | /// a token minted for somebody else's application is accepted. Google's own contract is that |
| | | 24 | | /// a <c>null</c> <see cref="GoogleJsonWebSignature.ValidationSettings.Audience" /> means "do |
| | | 25 | | /// not validate the audience at all", so the difference between enforcing that check and |
| | | 26 | | /// silently dropping it is one assignment in this file — a change that no test could see |
| | | 27 | | /// while the settings were built inline. |
| | | 28 | | /// </para> |
| | | 29 | | /// </remarks> |
| | | 30 | | public static class GoogleIdTokenValidationSettings |
| | | 31 | | { |
| | | 32 | | /// <summary> |
| | | 33 | | /// The settings for a deployment configured with <paramref name="options" />' client IDs. |
| | | 34 | | /// </summary> |
| | | 35 | | /// <remarks> |
| | | 36 | | /// Only the audience is set. The issuer (<c>accounts.google.com</c>), the signature against |
| | | 37 | | /// Google's published keys, and the expiry are the library's defaults, and overriding any of |
| | | 38 | | /// them here would be loosening a check NFR-13 requires rather than configuring one. |
| | | 39 | | /// </remarks> |
| | 5 | 40 | | public static GoogleJsonWebSignature.ValidationSettings For(GoogleSignInOptions options) => new() |
| | 5 | 41 | | { |
| | 5 | 42 | | // Never null, and never empty in practice: Startup resolves UnconfiguredGoogleIdTokenVerifier |
| | 5 | 43 | | // when no client is configured, so this verifier is only ever reached with at least one |
| | 5 | 44 | | // audience to check against. Passing the list straight through is what makes a token issued |
| | 5 | 45 | | // for another application fail even though Google signed it. |
| | 5 | 46 | | Audience = options.ClientIds |
| | 5 | 47 | | }; |
| | | 48 | | } |