From 009a0151c04902251019750759b66d537130daf5 Mon Sep 17 00:00:00 2001 From: lyric Date: Thu, 25 Aug 2016 14:23:16 +0800 Subject: [PATCH] repair the details --- README.md | 23 ++++++--------- const.go | 18 +++++++++--- doc.go | 32 +++++++++++++++++++++ server/server.go | 66 ++++++++++++++++++++++++------------------- server/server_test.go | 5 ++-- 5 files changed, 93 insertions(+), 51 deletions(-) create mode 100644 doc.go diff --git a/README.md b/README.md index 7bb2731..688f96c 100644 --- a/README.md +++ b/README.md @@ -2,11 +2,7 @@ > An open protocol to allow secure authorization in a simple and standard method from web, mobile and desktop applications. -[![License][License-Image]][License-Url] -[![ReportCard][ReportCard-Image]][ReportCard-Url] -[![Build][Build-Status-Image]][Build-Status-Url] -[![GoDoc][GoDoc-Image]][GoDoc-Url] -[![Release][Release-Image]][Release-Url] +[![License][License-Image]][License-Url] [![ReportCard][ReportCard-Image]][ReportCard-Url] [![Build][Build-Status-Image]][Build-Status-Url] [![GoDoc][GoDoc-Image]][GoDoc-Url] [![Release][Release-Image]][Release-Url] ## Protocol Flow @@ -44,7 +40,7 @@ $ go get -u gopkg.in/oauth2.v3/... package main import ( - "fmt" + "log" "net/http" "gopkg.in/oauth2.v3/manage" @@ -63,7 +59,7 @@ func main() { srv.SetAllowGetAccessRequest(true) srv.SetInternalErrorHandler(func(err error) { - fmt.Println("OAuth2 Error:",err.Error()) + log.Println("OAuth2 Error:", err.Error()) }) http.HandleFunc("/authorize", func(w http.ResponseWriter, r *http.Request) { @@ -74,10 +70,7 @@ func main() { }) http.HandleFunc("/token", func(w http.ResponseWriter, r *http.Request) { - err := srv.HandleTokenRequest(w, r) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - } + srv.HandleTokenRequest(w, r) }) http.ListenAndServe(":9096", nil) @@ -94,14 +87,14 @@ $ ./server ### Open in your web browser ``` -http://localhost:9096/token?grant_type=clientcredentials&client_id=1&client_secret=11&scope=all +http://localhost:9096/token?grant_type=client_credentials&client_id=1&client_secret=11&scope=read ``` -``` +``` json { - "access_token": "ZGF4ARHJPT2Y_QAIOJVL-Q", + "access_token": "ACPT7UYYNVWS2OAPFOHVUW", "expires_in": 7200, - "scope": "all", + "scope": "read", "token_type": "Bearer" } ``` diff --git a/const.go b/const.go index ccf7038..8a2fd71 100644 --- a/const.go +++ b/const.go @@ -10,7 +10,11 @@ const ( ) func (rt ResponseType) String() string { - return string(rt) + if rt == Code || + rt == Token { + return string(rt) + } + return "" } // GrantType authorization model @@ -20,11 +24,17 @@ type GrantType string const ( AuthorizationCode GrantType = "authorization_code" PasswordCredentials GrantType = "password" - ClientCredentials GrantType = "clientcredentials" - Refreshing GrantType = "refreshtoken" + ClientCredentials GrantType = "client_credentials" + Refreshing GrantType = "refresh_token" Implicit GrantType = "__implicit" ) func (gt GrantType) String() string { - return string(gt) + if gt == AuthorizationCode || + gt == PasswordCredentials || + gt == ClientCredentials || + gt == Refreshing { + return string(gt) + } + return "" } diff --git a/doc.go b/doc.go new file mode 100644 index 0000000..7fcf463 --- /dev/null +++ b/doc.go @@ -0,0 +1,32 @@ +/* +OAuth 2.0 server library for the Go programming language + + package main + + import ( + "net/http" + + "gopkg.in/oauth2.v3/manage" + "gopkg.in/oauth2.v3/server" + "gopkg.in/oauth2.v3/store" + ) + + func main() { + manager := manage.NewDefaultManager() + manager.MustTokenStorage(store.NewMemoryTokenStore()) + manager.MapClientStorage(store.NewTestClientStore()) + + srv := server.NewDefaultServer(manager) + http.HandleFunc("/authorize", func(w http.ResponseWriter, r *http.Request) { + srv.HandleAuthorizeRequest(w, r) + }) + http.HandleFunc("/token", func(w http.ResponseWriter, r *http.Request) { + srv.HandleTokenRequest(w, r) + }) + + http.ListenAndServe(":9096", nil) + } + +*/ + +package oauth2 diff --git a/server/server.go b/server/server.go index 4a3c869..b143218 100644 --- a/server/server.go +++ b/server/server.go @@ -121,26 +121,6 @@ func (s *Server) GetRedirectURI(req *AuthorizeRequest, data map[string]interface return } -// ValidationAuthorizeRequest the authorization request validation -func (s *Server) ValidationAuthorizeRequest(r *http.Request) (req *AuthorizeRequest, err error) { - if r.Method != "GET" { - err = errors.ErrInvalidRequest - return - } - redirectURI, err := url.QueryUnescape(r.FormValue("redirect_uri")) - if err != nil { - return - } - req = &AuthorizeRequest{ - RedirectURI: redirectURI, - ResponseType: oauth2.ResponseType(r.FormValue("response_type")), - ClientID: r.FormValue("client_id"), - State: r.FormValue("state"), - Scope: r.FormValue("scope"), - } - return -} - // CheckResponseType check allows response type func (s *Server) CheckResponseType(rt oauth2.ResponseType) bool { for _, art := range s.Config.AllowedResponseTypes { @@ -151,20 +131,41 @@ func (s *Server) CheckResponseType(rt oauth2.ResponseType) bool { return false } -// GetAuthorizeToken get authorization token(code) -func (s *Server) GetAuthorizeToken(req *AuthorizeRequest) (ti oauth2.TokenInfo, err error) { - if req.ResponseType == "" { - err = errors.ErrUnsupportedResponseType +// ValidationAuthorizeRequest the authorization request validation +func (s *Server) ValidationAuthorizeRequest(r *http.Request) (req *AuthorizeRequest, err error) { + redirectURI, err := url.QueryUnescape(r.FormValue("redirect_uri")) + if err != nil { return - } else if req.RedirectURI == "" || - req.ClientID == "" { + } + clientID := r.FormValue("client_id") + if r.Method != "GET" || + clientID == "" || + redirectURI == "" { err = errors.ErrInvalidRequest return } - if allowed := s.CheckResponseType(req.ResponseType); !allowed { + + resType := oauth2.ResponseType(r.FormValue("response_type")) + if resType.String() == "" { + err = errors.ErrUnsupportedResponseType + return + } else if allowed := s.CheckResponseType(resType); !allowed { err = errors.ErrUnauthorizedClient return } + + req = &AuthorizeRequest{ + RedirectURI: redirectURI, + ResponseType: resType, + ClientID: clientID, + State: r.FormValue("state"), + Scope: r.FormValue("scope"), + } + return +} + +// GetAuthorizeToken get authorization token(code) +func (s *Server) GetAuthorizeToken(req *AuthorizeRequest) (ti oauth2.TokenInfo, err error) { // check the client allows the grant type if fn := s.ClientAuthorizedHandler; fn != nil { gt := oauth2.AuthorizationCode @@ -180,6 +181,7 @@ func (s *Server) GetAuthorizeToken(req *AuthorizeRequest) (ti oauth2.TokenInfo, return } } + // check the client allows the authorized scope if fn := s.ClientScopeHandler; fn != nil { allowed, verr := fn(req.ClientID, req.Scope) @@ -191,6 +193,7 @@ func (s *Server) GetAuthorizeToken(req *AuthorizeRequest) (ti oauth2.TokenInfo, return } } + tgr := &oauth2.TokenGenerateRequest{ ClientID: req.ClientID, UserID: req.UserID, @@ -221,6 +224,7 @@ func (s *Server) HandleAuthorizeRequest(w http.ResponseWriter, r *http.Request) err = s.redirectError(w, req, verr) return } + // user authorization userID, verr := s.UserAuthorizationHandler(w, r) if verr != nil { @@ -230,6 +234,7 @@ func (s *Server) HandleAuthorizeRequest(w http.ResponseWriter, r *http.Request) return } req.UserID = userID + // specify the scope of authorization if fn := s.AuthorizeScopeHandler; fn != nil { scope, verr := fn(w, r) @@ -240,6 +245,7 @@ func (s *Server) HandleAuthorizeRequest(w http.ResponseWriter, r *http.Request) req.Scope = scope } } + // specify the expiration time of access token if fn := s.AccessTokenExpHandler; fn != nil { exp, verr := fn(w, r) @@ -249,6 +255,7 @@ func (s *Server) HandleAuthorizeRequest(w http.ResponseWriter, r *http.Request) } req.AccessTokenExp = exp } + ti, verr := s.GetAuthorizeToken(req) if verr != nil { err = s.redirectError(w, req, verr) @@ -260,12 +267,13 @@ func (s *Server) HandleAuthorizeRequest(w http.ResponseWriter, r *http.Request) // ValidationTokenRequest the token request validation func (s *Server) ValidationTokenRequest(r *http.Request) (gt oauth2.GrantType, tgr *oauth2.TokenGenerateRequest, err error) { - if v := r.Method; !(v == "POST" || (s.Config.AllowGetAccessRequest && v == "GET")) { + if v := r.Method; !(v == "POST" || + (s.Config.AllowGetAccessRequest && v == "GET")) { err = errors.ErrInvalidRequest return } gt = oauth2.GrantType(r.FormValue("grant_type")) - if gt == "" { + if gt.String() == "" { err = errors.ErrUnsupportedGrantType return } diff --git a/server/server_test.go b/server/server_test.go index a29ccbe..73f0588 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -8,7 +8,6 @@ import ( "testing" "github.com/gavv/httpexpect" - "gopkg.in/oauth2.v3" "gopkg.in/oauth2.v3/manage" "gopkg.in/oauth2.v3/models" @@ -169,7 +168,7 @@ func TestClientCredentials(t *testing.T) { srv = server.NewDefaultServer(manager) val := e.POST("/token"). - WithFormField("grant_type", "clientcredentials"). + WithFormField("grant_type", "client_credentials"). WithFormField("client_id", clientID). WithFormField("client_secret", clientSecret). WithFormField("scope", "all"). @@ -210,7 +209,7 @@ func TestRefreshing(t *testing.T) { refresh := jval.Object().Value("refresh_token").String().Raw() rval := e.POST("/token"). - WithFormField("grant_type", "refreshtoken"). + WithFormField("grant_type", "refresh_token"). WithFormField("client_id", clientID). WithFormField("client_secret", clientSecret). WithFormField("scope", "one").