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
23 changes: 8 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -44,7 +40,7 @@ $ go get -u gopkg.in/oauth2.v3/...
package main

import (
"fmt"
"log"
"net/http"

"gopkg.in/oauth2.v3/manage"
Expand All @@ -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) {
Expand All @@ -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)
Expand All @@ -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"
}
```
Expand Down
18 changes: 14 additions & 4 deletions const.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 ""
}
32 changes: 32 additions & 0 deletions doc.go
Original file line number Diff line number Diff line change
@@ -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
66 changes: 37 additions & 29 deletions server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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
Expand All @@ -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)
Expand All @@ -191,6 +193,7 @@ func (s *Server) GetAuthorizeToken(req *AuthorizeRequest) (ti oauth2.TokenInfo,
return
}
}

tgr := &oauth2.TokenGenerateRequest{
ClientID: req.ClientID,
UserID: req.UserID,
Expand Down Expand Up @@ -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 {
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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
}
Expand Down
5 changes: 2 additions & 3 deletions server/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"testing"

"github.com/gavv/httpexpect"

"gopkg.in/oauth2.v3"
"gopkg.in/oauth2.v3/manage"
"gopkg.in/oauth2.v3/models"
Expand Down Expand Up @@ -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").
Expand Down Expand Up @@ -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").
Expand Down