validateOAuth2ProviderAppTokenAudience validates that an OAuth2 provider app token is being used with the correct audience/resource server (RFC 8707).
(ctx context.Context, db database.Store, key database.APIKey, accessURL *url.URL, r *http.Request)
| 702 | // validateOAuth2ProviderAppTokenAudience validates that an OAuth2 provider app token |
| 703 | // is being used with the correct audience/resource server (RFC 8707). |
| 704 | func validateOAuth2ProviderAppTokenAudience(ctx context.Context, db database.Store, key database.APIKey, accessURL *url.URL, r *http.Request) error { |
| 705 | // Get the OAuth2 provider app token to check its audience |
| 706 | //nolint:gocritic // OAuth2 system context — audience validation for provider app tokens |
| 707 | token, err := db.GetOAuth2ProviderAppTokenByAPIKeyID(dbauthz.AsSystemOAuth2(ctx), key.ID) |
| 708 | if err != nil { |
| 709 | return xerrors.Errorf("failed to get OAuth2 token: %w", err) |
| 710 | } |
| 711 | |
| 712 | // If no audience is set, allow the request (for backward compatibility) |
| 713 | if !token.Audience.Valid || token.Audience.String == "" { |
| 714 | return nil |
| 715 | } |
| 716 | |
| 717 | // Extract the expected audience from the access URL |
| 718 | expectedAudience := extractExpectedAudience(accessURL, r) |
| 719 | |
| 720 | // Normalize both audience values for RFC 3986 compliant comparison |
| 721 | normalizedTokenAudience := normalizeAudienceURI(token.Audience.String) |
| 722 | normalizedExpectedAudience := normalizeAudienceURI(expectedAudience) |
| 723 | |
| 724 | // Validate that the token's audience matches the expected audience |
| 725 | if normalizedTokenAudience != normalizedExpectedAudience { |
| 726 | return xerrors.Errorf("token audience %q does not match expected audience %q", |
| 727 | token.Audience.String, expectedAudience) |
| 728 | } |
| 729 | |
| 730 | return nil |
| 731 | } |
| 732 | |
| 733 | // normalizeAudienceURI implements RFC 3986 URI normalization for OAuth2 audience comparison. |
| 734 | // This ensures consistent audience matching between authorization and token validation. |
no test coverage detected