// ExchangeWithAdditionalValues converts an authorization code into a token // and allows for additional URL values to be passed to the token endpoint. // This enables exchange functionality with non-standardized enpoints e.g. Microsoft Azure. func (c *Config) ExchangeWithAdditionalValues(ctx context.Context, code string, additionalValues url.Values) (*Token, error) { values := url.Values{ "grant_type": {"authorization_code"}, "code": {code}, "redirect_uri": internal.CondVal(c.RedirectURL), "scope": internal.CondVal(strings.Join(c.Scopes, " ")), } for key, value := range additionalValues { values[key] = value } return retrieveToken(ctx, c, values) }
// PasswordCredentialsToken converts a resource owner username and password // pair into a token. // // Per the RFC, this grant type should only be used "when there is a high // degree of trust between the resource owner and the client (e.g., the client // is part of the device operating system or a highly privileged application), // and when other authorization grant types are not available." // See https://tools.ietf.org/html/rfc6749#section-4.3 for more info. // // The HTTP client to use is derived from the context. // If nil, http.DefaultClient is used. func (c *Config) PasswordCredentialsToken(ctx context.Context, username, password string) (*Token, error) { return retrieveToken(ctx, c, url.Values{ "grant_type": {"password"}, "username": {username}, "password": {password}, "scope": internal.CondVal(strings.Join(c.Scopes, " ")), }) }
// AuthCodeURL returns a URL to OAuth 2.0 provider's consent page // that asks for permissions for the required scopes explicitly. // // State is a token to protect the user from CSRF attacks. You must // always provide a non-zero string and validate that it matches the // the state query parameter on your redirect callback. // See http://tools.ietf.org/html/rfc6749#section-10.12 for more info. // // Opts may include AccessTypeOnline or AccessTypeOffline, as well // as ApprovalForce. func (c *Config) AuthCodeURL(state string, opts ...AuthCodeOption) string { var buf bytes.Buffer buf.WriteString(c.Endpoint.AuthURL) v := url.Values{ "response_type": {"code"}, "client_id": {c.ClientID}, "redirect_uri": internal.CondVal(c.RedirectURL), "scope": internal.CondVal(strings.Join(c.Scopes, " ")), "state": internal.CondVal(state), } for _, opt := range opts { opt.setValue(v) } if strings.Contains(c.Endpoint.AuthURL, "?") { buf.WriteByte('&') } else { buf.WriteByte('?') } buf.WriteString(v.Encode()) return buf.String() }
// Token uses client credentials to retrieve a token. // The HTTP client to use is derived from the context. // If nil, http.DefaultClient is used. func (c *Config) Token(ctx context.Context) (*oauth2.Token, error) { return retrieveToken(ctx, c, url.Values{ "grant_type": {"client_credentials"}, "scope": internal.CondVal(strings.Join(c.Scopes, " ")), }) }
// Token refreshes the token by using a new client credentials request. // tokens received this way do not include a refresh token func (c *tokenSource) Token() (*oauth2.Token, error) { return retrieveToken(c.ctx, c.conf, url.Values{ "grant_type": {"client_credentials"}, "scope": internal.CondVal(strings.Join(c.conf.Scopes, " ")), }) }