Documentation ¶
Index ¶
- Variables
- func ExponentialRetryDuration(retry int) time.Duration
- func ExtractToken(authHeader string) string
- func NewTokenOption() *tokenOption
- func SetSecondaryCache(secondaryCache cache.Cache)
- type Client
- func (c *Client) OAuth2Token(cacheKey string, scopes []string, option *tokenOption) (*oauth2.Token, error)
- func (c *Client) OAuth2TokenWithoutCaching(scopes []string, option *tokenOption) (token *oauth2.Token, err error)
- func (c *Client) Request(cacheKey string, scopes []string, exec func(string) (*http.Response, error)) (*http.Response, error)
- func (c *Client) RequestWithCustomRetry(cacheKey string, scopes []string, numRetry int, ...) (*http.Response, error)
- func (c *Client) Token(cacheKey string, scopes []string, option *tokenOption) (string, error)
- type ExpiredTokenError
- type InternalServerError
- type PermissionDeniedError
- type SandError
- type Service
- func (s *Service) CheckRequest(r *http.Request, targetScopes []string, action string) (map[string]interface{}, error)
- func (s *Service) CheckRequestWithCustomRetry(r *http.Request, targetScopes []string, action string, numRetry int) (map[string]interface{}, error)
- func (s *Service) ErrorCode(err error) int
- func (s *Service) VerifyRequest(r *http.Request, opt *VerificationOption) (map[string]interface{}, error)
- func (s *Service) VerifyTokenWithCache(token string, opt *VerificationOption) (map[string]interface{}, error)
- type TokenWithExpiration
- type TooManyRequestsError
- type VerificationOption
Constants ¶
This section is empty.
Variables ¶
var ( // This margin should be the max time it takes for service to verify a token. // The estimated time values: // 1. 2 second: // Sand issued a token and respond the token back to the client // 2. 5 seconds: // Client opens a connection and sends a request to the service // 3. 5 + 5 = 10 seconds: // Service requests a service token from Sand. The default open_timeout (5 secs) plus timeout (5 secs) // 4. 5 + 5 = 10 seconds: // Service makes request to the Sand verification endpoint. The default open_timeout (5 secs) plus timeout (5 secs) RequireMinimumValidityTimeOnToken = 27.0 // Margin in seconds to compensate the possible delay on the expires_in seconds // from Sand server. TokenCompensateMargin = 3 * time.Second CacheMaxJitter = 15.0 )
Functions ¶
func ExtractToken ¶
ExtractToken extracts a bearer token from the Authorization header. The "bearer" keyword is case-insensitive
func NewTokenOption ¶
func NewTokenOption() *tokenOption
func SetSecondaryCache ¶
SetSecondaryCache sets or replaces the secondary cache used by Sand clients and services.
Types ¶
type Client ¶
type Client struct { //The client ID of the OAuth2 client credentials ClientID string //The client secret of the OAuth2 client credentials ClientSecret string //TokenURL: The token endpoint of the OAuth2 server, e.g., "https://oauth.example.com/oauth2/token" TokenURL string //SSLMinVersion is the minimum supported TLS version. Default is TLS 1.2. SSLMinVersion uint16 Timeout time.Duration //DefaultRetryCount is the default number of retries to perform with exponential backoff when //1. Clients receive 401 response from services //2. Clients' or services' connections to the OAuth2 server fails. //Default value is 5 DefaultRetryCount int //CacheRoot is the root of the cache key for storing tokens in the cache. //The overall cache key will look like: <CacheRoot>/<cacheType>/<some key> //Default value is "sand" CacheRoot string Verbose bool // contains filtered or unexported fields }
Client can be used to request token from an OAuth2 server
func NewClient ¶
NewClient returns a Client with default option values. The default expiration time is set to 3599 seconds. The primary cache is in-memory. The secondary cache is nil with this client. Use NewClientWithCache if you want use the secondary cache.
func (*Client) OAuth2Token ¶
func (c *Client) OAuth2Token(cacheKey string, scopes []string, option *tokenOption) (*oauth2.Token, error)
OAuth2Token returns an OAuth2 token retrieved from the OAuth2 server. It also puts the token in the cache up to specified amount of time.
func (*Client) OAuth2TokenWithoutCaching ¶
func (c *Client) OAuth2TokenWithoutCaching(scopes []string, option *tokenOption) (token *oauth2.Token, err error)
OAuth2TokenWithoutCaching makes the connection to the OAuth server and returns oauth2.Token The returned token could have empty accessToken.
func (*Client) Request ¶
func (c *Client) Request(cacheKey string, scopes []string, exec func(string) (*http.Response, error)) (*http.Response, error)
Request makes a service API request by first obtaining the access token from SAND. Then it deligates the token to the underlying function to make the service call. If the service returns 401, it performs exponential retry by requesting new tokens from SAND and make the service call. If the service returns 502, the service failed to connect to the authentication service and no retry will occur. Usage Example:
client.Request("some-service", []string{"s1", "s2"}, func(token string) (*http.Response, error) { // Make http request with "Bearer {token}" in the Authorization header // return the response and error })
func (*Client) RequestWithCustomRetry ¶
func (c *Client) RequestWithCustomRetry(cacheKey string, scopes []string, numRetry int, exec func(string) (*http.Response, error)) (*http.Response, error)
RequestWithCustomRetry allows specifying numRetry as the number of retries to use instead of the DefaultRetryCount, on a per-request basis. numRetry MUST be at least one so that if a client's token has expired, it can get a new token when retrying, at least once. Using a negative number for numRetry is equivalent to the "Request" function, which uses DefaultRetryCount. The retry durations are: 1, 2, 4, 8, 16,... seconds
type ExpiredTokenError ¶
type ExpiredTokenError struct {
SandError
}
ExpiredTokenError when a client receives a token that is already expired
type InternalServerError ¶
type InternalServerError struct {
SandError
}
InternalServerError is returned when the client receives a 401 accessing the authentication service or the target service
type PermissionDeniedError ¶
type PermissionDeniedError struct {
SandError
}
PermissionDeniedError when service receives 403 from Sand while verifying a client token.
type Service ¶
type Service struct { Client //The default resource name that this Service will check the token against. Resource string //Default context Context map[string]interface{} //The URL of the token verification endpoint, e.g., "https://oauth.example.com/warden/token/allowed" TokenVerifyURL string //The default expiry time for cache for invalid tokens and also valid tokens without expiry times //Default value is 3599 seconds //Only services need this because client tokens will always give expiry time DefaultExpDuration time.Duration //The scopes required for the service to access the token verification endpoint Scopes []string }
Service can be used to verify a token with SAND
func NewService ¶
func NewService(id, secret, tokenURL, resource, verifyURL string, scopes []string) (service *Service, err error)
NewService returns a Service struct.
func (*Service) CheckRequest ¶
func (s *Service) CheckRequest(r *http.Request, targetScopes []string, action string) (map[string]interface{}, error)
CheckRequest checks the bearer token of an incoming HTTP request and return response with 'allowed' true/false field. If the error is of type sand.ConnectionError, the service should respond with HTTP status code 502. Otherwise the client would perform unnecessary retries. Example with Gin:
func(c *gin.Context) { response, err := sandService.CheckRequest(c.Request, []string{"scope1", "scope2"}, "action") if err != nil || response["allowed"] != true { c.JSON(sandService.ErrorCode(err), err) //This would set 502 on ConnectionError } }
func (*Service) CheckRequestWithCustomRetry ¶
func (s *Service) CheckRequestWithCustomRetry(r *http.Request, targetScopes []string, action string, numRetry int) (map[string]interface{}, error)
CheckRequestWithCustomRetry allows specifying a positive number as number of retries to use instead of using DefaultRetryCount on a per-request basis. Using a negative number for numRetry is equivalent to the "Request" function
func (*Service) ErrorCode ¶
ErrorCode gets the HTTP error code based on the error type. By default it is 401 unauthorized; if the error is connection error, then it returns 502
func (*Service) VerifyRequest ¶
func (s *Service) VerifyRequest(r *http.Request, opt *VerificationOption) (map[string]interface{}, error)
VerifyRequest takes the token in a request and verifies with SAND Remember to set a reasonable NumRetry value (>= 0) for the VerificationOption
func (*Service) VerifyTokenWithCache ¶
func (s *Service) VerifyTokenWithCache(token string, opt *VerificationOption) (map[string]interface{}, error)
VerifyTokenWithCache tries to get the result for this token from the cache first. If not found in cache, if will make a token verification request with Sand.
type TokenWithExpiration ¶
type TooManyRequestsError ¶
type TooManyRequestsError struct {
SandError
}
TooManyRequestsError when service receives 429 from Sand while verifying a client token.