Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions auth/authorization_code.go
Original file line number Diff line number Diff line change
Expand Up @@ -402,14 +402,23 @@ func (h *AuthorizationCodeHandler) Authorize(ctx context.Context, req *http.Requ
}

// resourceMetadataURLFromChallenges returns a resource metadata URL from the given "WWW-Authenticate" header challenges,
// or the empty string if there is none.
// preferring a "Bearer" challenge and otherwise the first other scheme that carries one. It returns the empty string if
// there is none.
func resourceMetadataURLFromChallenges(cs []oauthex.Challenge) string {
var fallback string
for _, c := range cs {
if u := c.Params["resource_metadata"]; u != "" {
u := c.Params["resource_metadata"]
if u == "" {
continue
}
if strings.EqualFold(c.Scheme, "Bearer") {
return u
}
if fallback == "" {
fallback = u
}
}
return ""
return fallback
}

// scopesFromChallenges returns the scopes from the given "WWW-Authenticate" header challenges.
Expand Down
21 changes: 21 additions & 0 deletions auth/authorization_code_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1606,3 +1606,24 @@ func TestInitialTokenSource(t *testing.T) {
t.Errorf("expected access token 'set_token', got '%s'", tok.AccessToken)
}
}

func TestResourceMetadataURLFromChallengesUsesBearerChallenge(t *testing.T) {
challenges := []oauthex.Challenge{
{Scheme: "Basic", Params: map[string]string{"resource_metadata": "https://basic.example/metadata"}},
{Scheme: "Bearer", Params: map[string]string{"resource_metadata": "https://bearer.example/metadata"}},
}
if got, want := resourceMetadataURLFromChallenges(challenges), "https://bearer.example/metadata"; got != want {
t.Errorf("resourceMetadataURLFromChallenges() = %q, want %q", got, want)
}
}

func TestResourceMetadataURLFromChallengesFallsBackToOtherSchemes(t *testing.T) {
challenges := []oauthex.Challenge{
{Scheme: "Basic", Params: map[string]string{}},
{Scheme: "Digest", Params: map[string]string{"resource_metadata": "https://digest.example/metadata"}},
{Scheme: "Basic", Params: map[string]string{"resource_metadata": "https://basic.example/metadata"}},
}
if got, want := resourceMetadataURLFromChallenges(challenges), "https://digest.example/metadata"; got != want {
t.Errorf("resourceMetadataURLFromChallenges() = %q, want %q", got, want)
}
}
16 changes: 13 additions & 3 deletions auth/extauth/client_credentials.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,14 +236,24 @@ func protectedResourceMetadataURLs(metadataURL, resourceURL string) []prmURL {
}

// resourceMetadataURLFromChallenges returns a resource metadata URL from
// WWW-Authenticate challenges, or the empty string if there is none.
// WWW-Authenticate challenges, preferring a Bearer challenge and otherwise the
// first other scheme that carries one. It returns the empty string if there is
// none.
func resourceMetadataURLFromChallenges(cs []oauthex.Challenge) string {
var fallback string
for _, c := range cs {
if u := c.Params["resource_metadata"]; u != "" {
u := c.Params["resource_metadata"]
if u == "" {
continue
}
if strings.EqualFold(c.Scheme, "Bearer") {
return u
}
if fallback == "" {
fallback = u
}
}
return ""
return fallback
}

// scopesFromChallenges returns scopes from WWW-Authenticate challenges.
Expand Down
21 changes: 21 additions & 0 deletions auth/extauth/client_credentials_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -418,3 +418,24 @@ func TestSelectTokenAuthMethod(t *testing.T) {
})
}
}

func TestResourceMetadataURLFromChallengesUsesBearerChallenge(t *testing.T) {
challenges := []oauthex.Challenge{
{Scheme: "Basic", Params: map[string]string{"resource_metadata": "https://basic.example/metadata"}},
{Scheme: "Bearer", Params: map[string]string{"resource_metadata": "https://bearer.example/metadata"}},
}
if got, want := resourceMetadataURLFromChallenges(challenges), "https://bearer.example/metadata"; got != want {
t.Errorf("resourceMetadataURLFromChallenges() = %q, want %q", got, want)
}
}

func TestResourceMetadataURLFromChallengesFallsBackToOtherSchemes(t *testing.T) {
challenges := []oauthex.Challenge{
{Scheme: "Basic", Params: map[string]string{}},
{Scheme: "Digest", Params: map[string]string{"resource_metadata": "https://digest.example/metadata"}},
{Scheme: "Basic", Params: map[string]string{"resource_metadata": "https://basic.example/metadata"}},
}
if got, want := resourceMetadataURLFromChallenges(challenges), "https://digest.example/metadata"; got != want {
t.Errorf("resourceMetadataURLFromChallenges() = %q, want %q", got, want)
}
}
Loading