Skip to content

Commit f108728

Browse files
committed
allow code grant without secret if code verifier is defined
1 parent 62bc01d commit f108728

File tree

2 files changed

+19
-13
lines changed

2 files changed

+19
-13
lines changed

manage/manager.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ func (m *Manager) GenerateAuthToken(ctx context.Context, rt oauth2.ResponseType,
218218
}
219219
return ti, nil
220220
}
221-
221+
222222
// get authorization code data
223223
func (m *Manager) getAuthorizationCode(ctx context.Context, code string) (oauth2.TokenInfo, error) {
224224
ti, err := m.tokenStore.GetByCode(ctx, code)
@@ -288,7 +288,11 @@ func (m *Manager) GenerateAccessToken(ctx context.Context, gt oauth2.GrantType,
288288
return nil, errors.ErrInvalidClient
289289
}
290290
} else if len(cli.GetSecret()) > 0 && tgr.ClientSecret != cli.GetSecret() {
291-
return nil, errors.ErrInvalidClient
291+
// auth code flow doesnt require client_secret if used with PKCE and state parameter
292+
// this is especially useful for mobile apps, that cant hold the secret
293+
if !(gt == oauth2.AuthorizationCode && tgr.ClientSecret == "" && tgr.CodeVerifier != "") {
294+
return nil, errors.ErrInvalidClient
295+
}
292296
}
293297
if tgr.RedirectURI != "" {
294298
if err := m.validateURI(cli.GetDomain(), tgr.RedirectURI); err != nil {

server/server_test.go

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import (
55
"fmt"
66
"net/http"
77
"net/http/httptest"
8-
"net/url"
98
"testing"
109

1110
"github.com/gavv/httpexpect"
@@ -26,9 +25,10 @@ var (
2625
clientSecret = "11111111"
2726

2827
plainChallenge = "ThisIsAFourtyThreeCharactersLongStringThing"
29-
s256Challenge = "s256test"
30-
// echo s256test | sha256 | base64 | tr '/+' '_-'
31-
s256ChallengeHash = "W6YWc_4yHwYN-cGDgGmOMHF3l7KDy7VcRjf7q2FVF-o="
28+
s256Challenge = "s256tests256tests256tests256tests256tests256test"
29+
// sha2562 := sha256.Sum256([]byte(s256Challenge))
30+
// fmt.Printf(base64.URLEncoding.EncodeToString(sha2562[:]))
31+
s256ChallengeHash = "To2Xqv01cm16bC9Sf7KRRS8CO2SFss_HSMQOr3sdCDE="
3232
)
3333

3434
func init() {
@@ -107,7 +107,7 @@ func TestAuthorizeCode(t *testing.T) {
107107
WithQuery("client_id", clientID).
108108
WithQuery("scope", "all").
109109
WithQuery("state", "123").
110-
WithQuery("redirect_uri", url.QueryEscape(csrv.URL+"/oauth2")).
110+
WithQuery("redirect_uri", csrv.URL+"/oauth2").
111111
Expect().Status(http.StatusOK)
112112
}
113113

@@ -134,7 +134,7 @@ func TestAuthorizeCodeWithChallengePlain(t *testing.T) {
134134
WithFormField("grant_type", "authorization_code").
135135
WithFormField("client_id", clientID).
136136
WithFormField("code", code).
137-
WithBasicAuth("code_verifier", "testchallenge").
137+
WithFormField("code_verifier", plainChallenge).
138138
Expect().
139139
Status(http.StatusOK).
140140
JSON().Object()
@@ -152,13 +152,14 @@ func TestAuthorizeCodeWithChallengePlain(t *testing.T) {
152152
userID = "000000"
153153
return
154154
})
155+
srv.SetClientInfoHandler(server.ClientFormHandler)
155156

156157
e.GET("/authorize").
157158
WithQuery("response_type", "code").
158159
WithQuery("client_id", clientID).
159160
WithQuery("scope", "all").
160161
WithQuery("state", "123").
161-
WithQuery("redirect_uri", url.QueryEscape(csrv.URL+"/oauth2")).
162+
WithQuery("redirect_uri", csrv.URL+"/oauth2").
162163
WithQuery("code_challenge", plainChallenge).
163164
Expect().Status(http.StatusOK)
164165
}
@@ -186,7 +187,7 @@ func TestAuthorizeCodeWithChallengeS256(t *testing.T) {
186187
WithFormField("grant_type", "authorization_code").
187188
WithFormField("client_id", clientID).
188189
WithFormField("code", code).
189-
WithBasicAuth("code_verifier", s256Challenge).
190+
WithFormField("code_verifier", s256Challenge).
190191
Expect().
191192
Status(http.StatusOK).
192193
JSON().Object()
@@ -204,13 +205,14 @@ func TestAuthorizeCodeWithChallengeS256(t *testing.T) {
204205
userID = "000000"
205206
return
206207
})
208+
srv.SetClientInfoHandler(server.ClientFormHandler)
207209

208210
e.GET("/authorize").
209211
WithQuery("response_type", "code").
210212
WithQuery("client_id", clientID).
211213
WithQuery("scope", "all").
212214
WithQuery("state", "123").
213-
WithQuery("redirect_uri", url.QueryEscape(csrv.URL+"/oauth2")).
215+
WithQuery("redirect_uri", csrv.URL+"/oauth2").
214216
WithQuery("code_challenge", s256ChallengeHash).
215217
WithQuery("code_challenge_method", "S256").
216218
Expect().Status(http.StatusOK)
@@ -238,7 +240,7 @@ func TestImplicit(t *testing.T) {
238240
WithQuery("client_id", clientID).
239241
WithQuery("scope", "all").
240242
WithQuery("state", "123").
241-
WithQuery("redirect_uri", url.QueryEscape(csrv.URL+"/oauth2")).
243+
WithQuery("redirect_uri", csrv.URL+"/oauth2").
242244
Expect().Status(http.StatusOK)
243245
}
244246

@@ -384,7 +386,7 @@ func TestRefreshing(t *testing.T) {
384386
WithQuery("client_id", clientID).
385387
WithQuery("scope", "all").
386388
WithQuery("state", "123").
387-
WithQuery("redirect_uri", url.QueryEscape(csrv.URL+"/oauth2")).
389+
WithQuery("redirect_uri", csrv.URL+"/oauth2").
388390
Expect().Status(http.StatusOK)
389391
}
390392

0 commit comments

Comments
 (0)