From a6d141d555c9327055934dec4d6dce39f5008f1a Mon Sep 17 00:00:00 2001 From: Rui Yang Date: Wed, 10 Nov 2021 14:43:22 -0500 Subject: [PATCH 1/3] add client crendential grant type Signed-off-by: Rui Yang --- server/handlers.go | 25 +++++++++++++++++++++++++ server/oauth2.go | 1 + 2 files changed, 26 insertions(+) diff --git a/server/handlers.go b/server/handlers.go index 08004c6d0e..3f8049b05d 100755 --- a/server/handlers.go +++ b/server/handlers.go @@ -839,6 +839,8 @@ func (s *Server) handleToken(w http.ResponseWriter, r *http.Request) { s.withClientFromStorage(w, r, s.handleRefreshToken) case grantTypePassword: s.withClientFromStorage(w, r, s.handlePasswordGrant) + case grantTypeClientCredentials: + s.withClientFromStorage(w, r, s.handleClientCredentialsGrant) default: s.tokenErrHelper(w, errUnsupportedGrantType, "", http.StatusBadRequest) } @@ -1089,6 +1091,29 @@ func (s *Server) handleUserInfo(w http.ResponseWriter, r *http.Request) { w.Write(claims) } +func (s *Server) handleClientCredentialsGrant(w http.ResponseWriter, r *http.Request, client storage.Client) { + if err := r.ParseForm(); err != nil { + s.tokenErrHelper(w, errInvalidRequest, "Couldn't parse data", http.StatusBadRequest) + return + } + q := r.Form + + nonce := q.Get("nonce") + scopes := strings.Fields(q.Get("scope")) + + claims := storage.Claims{UserID: client.ID} + + accessToken := storage.NewID() + idToken, expiry, err := s.newIDToken(client.ID, claims, scopes, nonce, accessToken, "", "client") + if err != nil { + s.tokenErrHelper(w, errServerError, fmt.Sprintf("failed to create ID token: %v", err), http.StatusInternalServerError) + return + } + + resp := s.toAccessTokenResponse(idToken, accessToken, "", expiry) + s.writeAccessToken(w, resp) +} + func (s *Server) handlePasswordGrant(w http.ResponseWriter, r *http.Request, client storage.Client) { // Parse the fields if err := r.ParseForm(); err != nil { diff --git a/server/oauth2.go b/server/oauth2.go index bb0058a74a..1d4b2be808 100644 --- a/server/oauth2.go +++ b/server/oauth2.go @@ -132,6 +132,7 @@ const ( grantTypeImplicit = "implicit" grantTypePassword = "password" grantTypeDeviceCode = "urn:ietf:params:oauth:grant-type:device_code" + grantTypeClientCredentials = "client_credentials" ) const ( From be25663b732c82ab5d30a65739763b04e11c01c2 Mon Sep 17 00:00:00 2001 From: Michael Kelly Date: Fri, 3 Dec 2021 10:17:21 -0800 Subject: [PATCH 2/3] Fix issues in existing client credentials change This fixes two issues in the existing client credentials change: - client_credentials was not listed as a supported grant type - access tokens are not the storage ID Signed-off-by: Michael Kelly --- server/handlers.go | 8 +++++++- server/server.go | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/server/handlers.go b/server/handlers.go index 3f8049b05d..b4a7a91387 100755 --- a/server/handlers.go +++ b/server/handlers.go @@ -1103,7 +1103,13 @@ func (s *Server) handleClientCredentialsGrant(w http.ResponseWriter, r *http.Req claims := storage.Claims{UserID: client.ID} - accessToken := storage.NewID() + accessToken, err := s.newAccessToken(client.ID, claims, scopes, nonce, "client") + if err != nil { + s.logger.Errorf("failed to create new access token: %v", err) + s.tokenErrHelper(w, errServerError, err.Error(), http.StatusInternalServerError) + return + } + idToken, expiry, err := s.newIDToken(client.ID, claims, scopes, nonce, accessToken, "", "client") if err != nil { s.tokenErrHelper(w, errServerError, fmt.Sprintf("failed to create ID token: %v", err), http.StatusInternalServerError) diff --git a/server/server.go b/server/server.go index f23eb54b7c..2d503bce90 100755 --- a/server/server.go +++ b/server/server.go @@ -213,7 +213,7 @@ func newServer(ctx context.Context, c Config, rotationStrategy rotationStrategy) c.SupportedResponseTypes = []string{responseTypeCode} } - supportedGrant := []string{grantTypeAuthorizationCode, grantTypeRefreshToken, grantTypeDeviceCode} // default + supportedGrant := []string{grantTypeAuthorizationCode, grantTypeRefreshToken, grantTypeDeviceCode, grantTypeClientCredentials} // default supportedRes := make(map[string]bool) for _, respType := range c.SupportedResponseTypes { From 3f0f53187675afc8c3c79520f95c36cb54fe55b1 Mon Sep 17 00:00:00 2001 From: Rui Yang Date: Tue, 2 Aug 2022 13:48:38 -0400 Subject: [PATCH 3/3] Fix tests in TestServerSupportedGrants for client credentials Signed-off-by: Rui Yang --- server/server_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/server/server_test.go b/server/server_test.go index bedc336be3..6bda59ac5b 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -1756,17 +1756,17 @@ func TestServerSupportedGrants(t *testing.T) { { name: "Simple", config: func(c *Config) {}, - resGrants: []string{grantTypeAuthorizationCode, grantTypeRefreshToken, grantTypeDeviceCode}, + resGrants: []string{grantTypeAuthorizationCode, grantTypeClientCredentials, grantTypeRefreshToken, grantTypeDeviceCode}, }, { name: "With password connector", config: func(c *Config) { c.PasswordConnector = "local" }, - resGrants: []string{grantTypeAuthorizationCode, grantTypePassword, grantTypeRefreshToken, grantTypeDeviceCode}, + resGrants: []string{grantTypeAuthorizationCode, grantTypeClientCredentials, grantTypePassword, grantTypeRefreshToken, grantTypeDeviceCode}, }, { name: "With token response", config: func(c *Config) { c.SupportedResponseTypes = append(c.SupportedResponseTypes, responseTypeToken) }, - resGrants: []string{grantTypeAuthorizationCode, grantTypeImplicit, grantTypeRefreshToken, grantTypeDeviceCode}, + resGrants: []string{grantTypeAuthorizationCode, grantTypeClientCredentials, grantTypeImplicit, grantTypeRefreshToken, grantTypeDeviceCode}, }, { name: "All", @@ -1774,7 +1774,7 @@ func TestServerSupportedGrants(t *testing.T) { c.PasswordConnector = "local" c.SupportedResponseTypes = append(c.SupportedResponseTypes, responseTypeToken) }, - resGrants: []string{grantTypeAuthorizationCode, grantTypeImplicit, grantTypePassword, grantTypeRefreshToken, grantTypeDeviceCode}, + resGrants: []string{grantTypeAuthorizationCode, grantTypeClientCredentials, grantTypeImplicit, grantTypePassword, grantTypeRefreshToken, grantTypeDeviceCode}, }, }