mirror of
https://github.com/golang/oauth2.git
synced 2025-07-21 00:00:09 +08:00
Fail during conf init if auth or token URL is not valid.
This commit is contained in:
parent
7935ece62b
commit
70bd497612
@ -28,10 +28,7 @@ func Example_config() {
|
|||||||
|
|
||||||
// Redirect user to consent page to ask for permission
|
// Redirect user to consent page to ask for permission
|
||||||
// for the scopes specified above.
|
// for the scopes specified above.
|
||||||
url, err := conf.AuthCodeURL("")
|
url := conf.AuthCodeURL("")
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
fmt.Printf("Visit the URL for the auth dialog: %v", url)
|
fmt.Printf("Visit the URL for the auth dialog: %v", url)
|
||||||
|
|
||||||
// Use the exchange code that is handled by the redirect URL.
|
// Use the exchange code that is handled by the redirect URL.
|
||||||
|
@ -32,10 +32,7 @@ func Example_webServer() {
|
|||||||
|
|
||||||
// Redirect user to Google's consent page to ask for permission
|
// Redirect user to Google's consent page to ask for permission
|
||||||
// for the scopes specified above.
|
// for the scopes specified above.
|
||||||
url, err := config.AuthCodeURL("")
|
url := config.AuthCodeURL("")
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
fmt.Printf("Visit the URL for the auth dialog: %v", url)
|
fmt.Printf("Visit the URL for the auth dialog: %v", url)
|
||||||
|
|
||||||
// Handle the exchange code to initiate a transport
|
// Handle the exchange code to initiate a transport
|
||||||
|
15
jwt.go
15
jwt.go
@ -42,19 +42,23 @@ type JWTOptions struct {
|
|||||||
|
|
||||||
// NewJWTConfig creates a new configuration with the specified options
|
// NewJWTConfig creates a new configuration with the specified options
|
||||||
// and OAuth2 provider endpoint.
|
// and OAuth2 provider endpoint.
|
||||||
func NewJWTConfig(opts *JWTOptions, aud string) (*JWTConfig, error) {
|
func NewJWTConfig(opts *JWTOptions, aud string) (conf *JWTConfig, err error) {
|
||||||
|
var audURL *url.URL
|
||||||
|
if audURL, err = url.Parse(aud); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
contents, err := ioutil.ReadFile(opts.PemFilename)
|
contents, err := ioutil.ReadFile(opts.PemFilename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &JWTConfig{opts: opts, aud: aud, signature: contents}, nil
|
return &JWTConfig{opts: opts, aud: audURL, signature: contents}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// JWTConfig represents an OAuth 2.0 provider and client options to
|
// JWTConfig represents an OAuth 2.0 provider and client options to
|
||||||
// provide authorized transports with a Bearer JWT token.
|
// provide authorized transports with a Bearer JWT token.
|
||||||
type JWTConfig struct {
|
type JWTConfig struct {
|
||||||
opts *JWTOptions
|
opts *JWTOptions
|
||||||
aud string
|
aud *url.URL
|
||||||
signature []byte
|
signature []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,7 +77,6 @@ func (c *JWTConfig) NewTransportWithUser(user string) Transport {
|
|||||||
// fetchToken retrieves a new access token and updates the existing token
|
// fetchToken retrieves a new access token and updates the existing token
|
||||||
// with the newly fetched credentials.
|
// with the newly fetched credentials.
|
||||||
func (c *JWTConfig) FetchToken(existing *Token) (token *Token, err error) {
|
func (c *JWTConfig) FetchToken(existing *Token) (token *Token, err error) {
|
||||||
|
|
||||||
if existing == nil {
|
if existing == nil {
|
||||||
existing = &Token{}
|
existing = &Token{}
|
||||||
}
|
}
|
||||||
@ -81,7 +84,7 @@ func (c *JWTConfig) FetchToken(existing *Token) (token *Token, err error) {
|
|||||||
claimSet := &jws.ClaimSet{
|
claimSet := &jws.ClaimSet{
|
||||||
Iss: c.opts.Email,
|
Iss: c.opts.Email,
|
||||||
Scope: strings.Join(c.opts.Scopes, " "),
|
Scope: strings.Join(c.opts.Scopes, " "),
|
||||||
Aud: c.aud,
|
Aud: c.aud.String(),
|
||||||
}
|
}
|
||||||
|
|
||||||
if existing.Subject != "" {
|
if existing.Subject != "" {
|
||||||
@ -100,7 +103,7 @@ func (c *JWTConfig) FetchToken(existing *Token) (token *Token, err error) {
|
|||||||
v.Set("assertion", payload)
|
v.Set("assertion", payload)
|
||||||
|
|
||||||
// Make a request with assertion to get a new token.
|
// Make a request with assertion to get a new token.
|
||||||
resp, err := http.DefaultClient.PostForm(c.aud, v)
|
resp, err := http.DefaultClient.PostForm(c.aud.String(), v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
46
oauth2.go
46
oauth2.go
@ -78,16 +78,19 @@ type Options struct {
|
|||||||
|
|
||||||
// NewConfig creates a generic OAuth 2.0 configuration that talks
|
// NewConfig creates a generic OAuth 2.0 configuration that talks
|
||||||
// to an OAuth 2.0 provider specified with authURL and tokenURL.
|
// to an OAuth 2.0 provider specified with authURL and tokenURL.
|
||||||
func NewConfig(opts *Options, authURL, tokenURL string) (*Config, error) {
|
func NewConfig(opts *Options, authURL, tokenURL string) (conf *Config, err error) {
|
||||||
conf := &Config{
|
var aURL, tURL *url.URL
|
||||||
opts: opts,
|
if aURL, err = url.Parse(authURL); err != nil {
|
||||||
authURL: authURL,
|
return
|
||||||
tokenURL: tokenURL,
|
|
||||||
}
|
}
|
||||||
if err := conf.validate(); err != nil {
|
if tURL, err = url.Parse(tokenURL); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
conf = &Config{opts: opts, authURL: aURL, tokenURL: tURL}
|
||||||
|
if err = conf.validate(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return conf, nil
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Config represents the configuration of an OAuth 2.0 consumer client.
|
// Config represents the configuration of an OAuth 2.0 consumer client.
|
||||||
@ -95,17 +98,22 @@ type Config struct {
|
|||||||
opts *Options
|
opts *Options
|
||||||
// AuthURL is the URL the user will be directed to
|
// AuthURL is the URL the user will be directed to
|
||||||
// in order to grant access.
|
// in order to grant access.
|
||||||
authURL string
|
authURL *url.URL
|
||||||
// TokenURL is the URL used to retrieve OAuth tokens.
|
// TokenURL is the URL used to retrieve OAuth tokens.
|
||||||
tokenURL string
|
tokenURL *url.URL
|
||||||
}
|
}
|
||||||
|
|
||||||
// AuthCodeURL returns a URL to OAuth 2.0 provider's consent page
|
// AuthCodeURL returns a URL to OAuth 2.0 provider's consent page
|
||||||
// that asks for permissions for the required scopes explicitly.
|
// that asks for permissions for the required scopes explicitly.
|
||||||
func (c *Config) AuthCodeURL(state string) (authURL string, err error) {
|
func (c *Config) AuthCodeURL(state string) (authURL string) {
|
||||||
u, err := url.Parse(c.authURL)
|
u := url.URL{
|
||||||
if err != nil {
|
Scheme: c.authURL.Scheme,
|
||||||
return
|
Opaque: c.authURL.Opaque,
|
||||||
|
User: c.authURL.User,
|
||||||
|
Host: c.authURL.Host,
|
||||||
|
Path: c.authURL.Path,
|
||||||
|
RawQuery: c.authURL.RawQuery,
|
||||||
|
Fragment: c.authURL.Fragment,
|
||||||
}
|
}
|
||||||
q := url.Values{
|
q := url.Values{
|
||||||
"response_type": {"code"},
|
"response_type": {"code"},
|
||||||
@ -121,7 +129,7 @@ func (c *Config) AuthCodeURL(state string) (authURL string, err error) {
|
|||||||
} else {
|
} else {
|
||||||
u.RawQuery += "&" + q
|
u.RawQuery += "&" + q
|
||||||
}
|
}
|
||||||
return u.String(), nil
|
return u.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTransport creates a new authorizable transport. It doesn't
|
// NewTransport creates a new authorizable transport. It doesn't
|
||||||
@ -176,14 +184,6 @@ func (c *Config) validate() error {
|
|||||||
if c.opts.RedirectURL == "" {
|
if c.opts.RedirectURL == "" {
|
||||||
return errors.New("A redirect URL should be provided.")
|
return errors.New("A redirect URL should be provided.")
|
||||||
}
|
}
|
||||||
// TODO(jbd): Validate the URLs. Maybe convert them to URL
|
|
||||||
// objects on construction.
|
|
||||||
if c.authURL == "" {
|
|
||||||
return errors.New("An auth URL should be provided.")
|
|
||||||
}
|
|
||||||
if c.tokenURL == "" {
|
|
||||||
return errors.New("A token URL should be provided.")
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,7 +206,7 @@ func (c *Config) exchange(exchangeCode string) (*Token, error) {
|
|||||||
func (c *Config) updateToken(tok *Token, v url.Values) error {
|
func (c *Config) updateToken(tok *Token, v url.Values) error {
|
||||||
v.Set("client_id", c.opts.ClientID)
|
v.Set("client_id", c.opts.ClientID)
|
||||||
v.Set("client_secret", c.opts.ClientSecret)
|
v.Set("client_secret", c.opts.ClientSecret)
|
||||||
r, err := http.DefaultClient.PostForm(c.tokenURL, v)
|
r, err := http.DefaultClient.PostForm(c.tokenURL.String(), v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -36,10 +36,7 @@ func newTestConf() *Config {
|
|||||||
|
|
||||||
func TestAuthCodeURL(t *testing.T) {
|
func TestAuthCodeURL(t *testing.T) {
|
||||||
conf := newTestConf()
|
conf := newTestConf()
|
||||||
url, err := conf.AuthCodeURL("foo")
|
url := conf.AuthCodeURL("foo")
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Expected to generate an auth URL, failed with %v.", err)
|
|
||||||
}
|
|
||||||
if url != "auth-url?access_type=offline&approval_prompt=force&client_id=CLIENT_ID&redirect_uri=REDIRECT_URL&response_type=code&scope=scope1+scope2&state=foo" {
|
if url != "auth-url?access_type=offline&approval_prompt=force&client_id=CLIENT_ID&redirect_uri=REDIRECT_URL&response_type=code&scope=scope1+scope2&state=foo" {
|
||||||
t.Fatalf("Generated auth URL is not the expected. Found %v.", url)
|
t.Fatalf("Generated auth URL is not the expected. Found %v.", url)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user