Skip to content

Commit 6584d34

Browse files
fix: scope parameter ignored in refresh flow (#5)
1 parent 5f46c1a commit 6584d34

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+842
-479
lines changed

README.md

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22

33
This is a hard fork of [ORY Fosite](https://github.com/ory/fosite) under the
44
[Apache 2.0 License](LICENSE) for the purpose of performing self-maintenance of
5-
this critical dependency.
5+
this critical Authelia dependency.
66

77
We however:
88

99
- Acknowledge the amazing hard work of the ORY developers in making such an
1010
amazing framework that we can do this with.
11-
- Plan to continue to contribute back to te ORY Fosite and related projects.
11+
- Plan to continue to contribute back to te ORY fosite and related projects.
1212
- Have ensured the licensing is unchanged in this fork of the library.
1313
- Do not have a formal affiliation with ORY and individuals utilizing this
1414
library should not allow their usage to be a reflection on ORY as this library
@@ -21,18 +21,33 @@ following list of differences:
2121

2222
- [x] Module path changed from `github.com/ory/fosite` to
2323
`authelia.com/provider/oauth2`.
24+
- Documentation:
25+
- [ ] Add spec support documentation
26+
- Overhaul testing:
27+
- [ ] Ensure all tests and subtests are well named
28+
- [ ] Ensure all tests are simplified where possible
29+
- [ ] Restore/Implement conformance tests
2430
- Rename interfaces and implementations:
2531
- [x] `OAuth2Provider` to `Provider`.
2632
- [ ] `Fosite` to `TBA`.
27-
- [x] Minimum dependency is go version 1.21.
33+
- [x] Minimum dependency is go version 1.21
34+
- [ ] Replace string values with constants where applicable
35+
- [ ] Simplify the internal JWT logic to leverage `github.com/golang-jwt/jwt/v5`
36+
- [ ] Implement internal JWKS logic
2837
- Fixes:
2938
- [x] Basic Scheme Rejects Special Characters
30-
2314625eb1f21987a9199fb1cdf6da6cee4df965
31-
- [x] RFC9068 must condition ignored f4652d60c850d167da00e2d2fe9096776eff9465
32-
- [ ] Refresh Flow ignores requested scope
33-
- [ ] Refresh Flow does not set original request ID early enough
34-
- [ ] PKCE Flow session generated needlessly
35-
- [ ] OpenID Flows ignore empty redirect uri
39+
<sup>[commit](https://github.com/authelia/oauth2-provider/commit/2314625eb1f21987a9199fb1cdf6da6cee4df965)</sup>
40+
- [x] RFC9068 must condition ignored
41+
<sup>[commit](https://github.com/authelia/oauth2-provider/commit/f4652d60c850d167da00e2d2fe9096776eff9465)</sup>
42+
- Refresh Flow:
43+
- [x] Requested scope ignored
44+
- [x] Original request id not set early enough
45+
- PKCE Flow
46+
- [ ] Session generated needlessly
47+
- [ ] Failure to fetch session causes an error even when not enforced
48+
- OpenID Flows:
49+
- [x] Absence of Redirect URI does not result in an error
50+
<sup>[commit](https://github.com/authelia/oauth2-provider/commit/f4652d60c850d167da00e2d2fe9096776eff9465)</sup>
3651
- [ ] Decode id_token_hint with correct signer
3752
- [ ] Write Revocation Response does not correctly error
3853
- [ ] Invalid Token base 64 error not mapped to RFC
@@ -42,6 +57,7 @@ following list of differences:
4257
- Features:
4358
- [ ] Customizable Token Prefix
4459
- [ ] JWE support for Client Authentication and Issuance
60+
- [ ] UserInfo support
4561
- [ ] JARM support
4662
- [ ] Revocation Flow per policy can decide to revoke Refresh Tokens on
4763
request
@@ -63,11 +79,6 @@ following list of differences:
6379
- [x] `github.com/form3tech-oss/jwt-go`
6480
- [x] `github.com/dgrijalva/jwt-go`
6581
- Migration of the following dependencies:
82+
- [ ] `github.com/go-jose/go-jose/v3` => `github.com/golang-jwt/jwt/v5`
6683
- [x] `github.com/golang/mock` => `github.com/uber-go/mock`
6784
- [x] `github.com/cristalhq/jwt/v4` => `github.com/golang-jwt/jwt/v5`
68-
69-
## TODO
70-
71-
- Consolidate JWT and JOSE dependencies
72-
- Remove unecessary dependencies and/or abstract them
73-
- Apply downstream fixes

access_error_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ func TestWriteAccessError(t *testing.T) {
3434
}
3535

3636
func TestWriteAccessError_RFC6749(t *testing.T) {
37-
// https://tools.ietf.org/html/rfc6749#section-5.2
37+
// https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
3838

3939
config := new(Config)
4040
provider := &Fosite{Config: config}

access_request.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,22 @@ func NewAccessRequest(session Session) *AccessRequest {
2323
func (a *AccessRequest) GetGrantTypes() Arguments {
2424
return a.GrantTypes
2525
}
26+
27+
func (a *AccessRequest) SetGrantedScopes(scopes Arguments) {
28+
a.GrantedScope = scopes
29+
}
30+
31+
func (a *AccessRequest) SanitizeRestoreRefreshTokenOriginalRequester(requester Requester) Requester {
32+
r := a.Sanitize(nil).(*Request)
33+
34+
ar := &AccessRequest{
35+
Request: *r,
36+
}
37+
38+
ar.SetID(requester.GetID())
39+
40+
ar.SetRequestedScopes(requester.GetRequestedScopes())
41+
ar.SetGrantedScopes(requester.GetGrantedScopes())
42+
43+
return ar
44+
}

access_request_handler.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import (
1515
)
1616

1717
// Implements
18-
// - https://tools.ietf.org/html/rfc6749#section-2.3.1
18+
// - https://datatracker.ietf.org/doc/html/rfc6749#section-2.3.1
1919
// Clients in possession of a client password MAY use the HTTP Basic
2020
// authentication scheme as defined in [RFC2617] to authenticate with
2121
// the authorization server. The client identifier is encoded using the
@@ -31,7 +31,7 @@ import (
3131
// password-based HTTP authentication schemes). The parameters can only
3232
// be transmitted in the request-body and MUST NOT be included in the
3333
// request URI.
34-
// - https://tools.ietf.org/html/rfc6749#section-3.2.1
34+
// - https://datatracker.ietf.org/doc/html/rfc6749#section-3.2.1
3535
// - Confidential clients or other clients issued client credentials MUST
3636
// authenticate with the authorization server as described in
3737
// Section 2.3 when making requests to the token endpoint.

access_response.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ package oauth2
66
import (
77
"strings"
88
"time"
9+
10+
"authelia.com/provider/oauth2/internal/consts"
911
)
1012

1113
func NewAccessResponse() *AccessResponse {
@@ -21,11 +23,11 @@ type AccessResponse struct {
2123
}
2224

2325
func (a *AccessResponse) SetScopes(scopes Arguments) {
24-
a.SetExtra("scope", strings.Join(scopes, " "))
26+
a.SetExtra(consts.AccessResponseScope, strings.Join(scopes, " "))
2527
}
2628

2729
func (a *AccessResponse) SetExpiresIn(expiresIn time.Duration) {
28-
a.SetExtra("expires_in", int64(expiresIn/time.Second))
30+
a.SetExtra(consts.AccessResponseExpiresIn, int64(expiresIn/time.Second))
2931
}
3032

3133
func (a *AccessResponse) SetExtra(key string, value any) {
@@ -53,7 +55,7 @@ func (a *AccessResponse) GetTokenType() string {
5355
}
5456

5557
func (a *AccessResponse) ToMap() map[string]any {
56-
a.Extra["access_token"] = a.GetAccessToken()
57-
a.Extra["token_type"] = a.GetTokenType()
58+
a.Extra[consts.AccessResponseAccessToken] = a.GetAccessToken()
59+
a.Extra[consts.AccessResponseTokenType] = a.GetTokenType()
5860
return a.Extra
5961
}

access_response_test.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,21 @@ import (
99
"github.com/stretchr/testify/assert"
1010

1111
. "authelia.com/provider/oauth2"
12+
"authelia.com/provider/oauth2/internal/consts"
1213
)
1314

1415
func TestAccessResponse(t *testing.T) {
1516
ar := NewAccessResponse()
1617
ar.SetAccessToken("access")
17-
ar.SetTokenType("bearer")
18-
ar.SetExtra("access_token", "invalid")
18+
ar.SetTokenType(BearerAccessToken)
19+
ar.SetExtra(consts.AccessResponseAccessToken, "invalid")
1920
ar.SetExtra("foo", "bar")
2021
assert.Equal(t, "access", ar.GetAccessToken())
21-
assert.Equal(t, "bearer", ar.GetTokenType())
22+
assert.Equal(t, BearerAccessToken, ar.GetTokenType())
2223
assert.Equal(t, "bar", ar.GetExtra("foo"))
2324
assert.Equal(t, map[string]any{
24-
"access_token": "access",
25-
"token_type": "bearer",
26-
"foo": "bar",
25+
consts.AccessResponseAccessToken: "access",
26+
consts.AccessResponseTokenType: BearerAccessToken,
27+
"foo": "bar",
2728
}, ar.ToMap())
2829
}

authorize_error_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@ import (
1818
)
1919

2020
// Test for
21-
// - https://tools.ietf.org/html/rfc6749#section-4.1.2.1
21+
// - https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.2.1
2222
// If the request fails due to a missing, invalid, or mismatching
2323
// redirection URI, or if the client identifier is missing or invalid,
2424
// the authorization server SHOULD inform the resource owner of the
2525
// error and MUST NOT automatically redirect the user-agent to the
2626
// invalid redirection URI.
27-
// - https://tools.ietf.org/html/rfc6749#section-3.1.2
27+
// - https://datatracker.ietf.org/doc/html/rfc6749#section-3.1.2
2828
// The redirection endpoint URI MUST be an absolute URI as defined by
2929
// [RFC3986] Section 4.3. The endpoint URI MAY include an
3030
// "application/x-www-form-urlencoded" formatted (per Appendix B) query

authorize_helper.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ var DefaultFormPostTemplate = template.Must(template.New("form_post").Parse(`<ht
3636
//
3737
// Considered specifications
3838
//
39-
// - https://tools.ietf.org/html/rfc6749#section-3.1.2.3
39+
// - https://datatracker.ietf.org/doc/html/rfc6749#section-3.1.2.3
4040
// If multiple redirection URIs have been registered, if only part of
4141
// the redirection URI has been registered, or if no redirection URI has
4242
// been registered, the client MUST include a redirection URI with the
@@ -50,7 +50,7 @@ var DefaultFormPostTemplate = template.Must(template.New("form_post").Parse(`<ht
5050
// redirection URI, the authorization server MUST compare the two URIs
5151
// using simple string comparison as defined in [RFC3986] Section 6.2.1.
5252
//
53-
// * https://tools.ietf.org/html/rfc6819#section-4.4.1.7
53+
// * https://datatracker.ietf.org/doc/html/rfc6819#section-4.4.1.7
5454
// - The authorization server may also enforce the usage and validation
5555
// of pre-registered redirect URIs (see Section 5.2.3.5). This will
5656
// allow for early recognition of authorization "code" disclosure to
@@ -87,7 +87,7 @@ func MatchRedirectURIWithClientRedirectURIs(rawurl string, client Client) (*url.
8787
// an IPv6 URI http://[::1] a client is allowed to request a dynamic port and the server MUST accept
8888
// it as a valid redirection uri.
8989
//
90-
// https://tools.ietf.org/html/rfc8252#section-7.3
90+
// https://datatracker.ietf.org/doc/html/rfc8252#section-7.3
9191
// Native apps that are able to open a port on the loopback network
9292
// interface without needing special permissions (typically, those on
9393
// desktop operating systems) can use the loopback interface to receive
@@ -127,7 +127,7 @@ func isMatchingAsLoopback(requested *url.URL, registeredURI string) bool {
127127
// Loopback redirect URIs use the "http" scheme and are constructed with
128128
// the loopback IP literal and whatever port the client is listening on.
129129
//
130-
// Source: https://tools.ietf.org/html/rfc8252#section-7.3
130+
// Source: https://datatracker.ietf.org/doc/html/rfc8252#section-7.3
131131
if requested.Scheme == "http" &&
132132
isLoopbackAddress(requested.Host) &&
133133
registered.Hostname() == requested.Hostname() &&
@@ -152,12 +152,12 @@ func isLoopbackAddress(address string) bool {
152152

153153
// IsValidRedirectURI validates a redirect_uri as specified in:
154154
//
155-
// * https://tools.ietf.org/html/rfc6749#section-3.1.2
155+
// * https://datatracker.ietf.org/doc/html/rfc6749#section-3.1.2
156156
// - The redirection endpoint URI MUST be an absolute URI as defined by [RFC3986] Section 4.3.
157157
// - The endpoint URI MUST NOT include a fragment component.
158-
// - https://tools.ietf.org/html/rfc3986#section-4.3
158+
// - https://datatracker.ietf.org/doc/html/rfc3986#section-4.3
159159
// absolute-URI = scheme ":" hier-part [ "?" query ]
160-
// - https://tools.ietf.org/html/rfc6819#section-5.1.1
160+
// - https://datatracker.ietf.org/doc/html/rfc6819#section-5.1.1
161161
func IsValidRedirectURI(redirectURI *url.URL) bool {
162162
// We need to explicitly check for a scheme
163163
if !urls.IsRequestURL(redirectURI.String()) {

authorize_request_handler.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ func (f *Fosite) validateAuthorizeScope(ctx context.Context, _ *http.Request, re
200200
}
201201

202202
func (f *Fosite) validateResponseTypes(r *http.Request, request *AuthorizeRequest) error {
203-
// https://tools.ietf.org/html/rfc6749#section-3.1.1
203+
// https://datatracker.ietf.org/doc/html/rfc6749#section-3.1.1
204204
// Extension response types MAY contain a space-delimited (%x20) list of
205205
// values, where the order of values does not matter (e.g., response
206206
// type "a b" is the same as "b a"). The meaning of such composite
@@ -414,7 +414,7 @@ func (f *Fosite) newAuthorizeRequest(ctx context.Context, r *http.Request, isPAR
414414
// The "state" parameter should be used to link the authorization
415415
// request with the redirect URI used to deliver the access token (Section 5.3.5).
416416
//
417-
// https://tools.ietf.org/html/rfc6819#section-4.4.1.8
417+
// https://datatracker.ietf.org/doc/html/rfc6819#section-4.4.1.8
418418
// The "state" parameter should not be guessable
419419
if len(request.State) < f.GetMinParameterEntropy(ctx) {
420420
// We're assuming that using less then, by default, 8 characters for the state can not be considered "unguessable"

authorize_write.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ func (f *Fosite) WriteAuthorizeResponse(ctx context.Context, rw http.ResponseWri
5656
}
5757
}
5858

59-
// https://tools.ietf.org/html/rfc6749#section-4.1.1
59+
// https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.1
6060
// When a decision is established, the authorization server directs the
6161
// user-agent to the provided client redirection URI using an HTTP
6262
// redirection response, or by other means available to it via the

0 commit comments

Comments
 (0)