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
8 changes: 5 additions & 3 deletions oauthex/resource_meta.go
Original file line number Diff line number Diff line change
Expand Up @@ -289,9 +289,11 @@ func parseSingleChallenge(s string) (Challenge, error) {
value = strings.TrimSpace(paramsStr[:commaPos])
paramsStr = strings.TrimSpace(paramsStr[commaPos:]) // Keep comma for next check
}
}
if value == "" {
return Challenge{}, fmt.Errorf("no value for auth param %q", key)
// A token is one or more characters. A quoted string may be empty
// (RFC 9110, section 5.6.4), so only an unquoted value is checked here.
if value == "" {
return Challenge{}, fmt.Errorf("no value for auth param %q", key)
}
}

// Per RFC 9110, parameter keys are case-insensitive.
Expand Down
36 changes: 36 additions & 0 deletions oauthex/resource_meta_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,28 @@ func TestParseWWWAuthenticateEscapedBackslash(t *testing.T) {
}
}

// A quoted string may be empty. An empty realm or error_description must not
// make the whole header unparseable, or the auth handlers never see the
// resource_metadata parameter that follows it.
func TestParseWWWAuthenticateEmptyQuotedValue(t *testing.T) {
got, err := ParseWWWAuthenticate([]string{
`Bearer realm="", error_description="", resource_metadata="https://example.com/.well-known/oauth-protected-resource"`,
})
if err != nil {
t.Fatal(err)
}
want := []Challenge{
{Scheme: "bearer", Params: map[string]string{
"realm": "",
"error_description": "",
"resource_metadata": "https://example.com/.well-known/oauth-protected-resource",
}},
}
if !reflect.DeepEqual(got, want) {
t.Errorf("ParseWWWAuthenticate() = %+v, want %+v", got, want)
}
}

func TestSplitChallengesError(t *testing.T) {
if _, err := splitChallenges(`"Bearer"`); err == nil {
t.Fatal("got nil, want error")
Expand Down Expand Up @@ -192,6 +214,20 @@ func TestParseSingleChallenge(t *testing.T) {
input: "Bearer realm=",
wantErr: true,
},
{
name: "empty quoted param",
input: `Bearer realm="", error="invalid_token"`,
want: Challenge{
Scheme: "bearer",
Params: map[string]string{"realm": "", "error": "invalid_token"},
},
wantErr: false,
},
{
name: "malformed param - no value before comma",
input: `Bearer realm=, error="invalid_token"`,
wantErr: true,
},
{
name: "malformed param - unterminated quote",
input: `Bearer realm="example`,
Expand Down
Loading