Documentation ¶
Index ¶
- Constants
- Variables
- func AccessTokenFromRequest(req *http.Request) string
- func GetRedirectURIFromRequestValues(values url.Values) (string, error)
- func HierarchicScopeStrategy(haystack []string, needle string) bool
- func IsRedirectURISecure(redirectURI *url.URL) bool
- func IsValidRedirectURI(redirectURI *url.URL) bool
- func MatchRedirectURIWithClientRedirectURIs(rawurl string, client Client) (*url.URL, error)
- func NewContext() context.Context
- func StringInSlice(needle string, haystack []string) bool
- type AccessRequest
- type AccessRequester
- type AccessResponder
- type AccessResponse
- func (a *AccessResponse) GetAccessToken() string
- func (a *AccessResponse) GetExtra(key string) interface{}
- func (a *AccessResponse) GetTokenType() string
- func (a *AccessResponse) SetAccessToken(token string)
- func (a *AccessResponse) SetExpiresIn(expiresIn time.Duration)
- func (a *AccessResponse) SetExtra(key string, value interface{})
- func (a *AccessResponse) SetScopes(scopes Arguments)
- func (a *AccessResponse) SetTokenType(name string)
- func (a *AccessResponse) ToMap() map[string]interface{}
- type Arguments
- type AuthorizeEndpointHandler
- type AuthorizeEndpointHandlers
- type AuthorizeRequest
- func (d *AuthorizeRequest) DidHandleAllResponseTypes() bool
- func (d *AuthorizeRequest) GetRedirectURI() *url.URL
- func (d *AuthorizeRequest) GetResponseTypes() Arguments
- func (d *AuthorizeRequest) GetState() string
- func (d *AuthorizeRequest) IsRedirectURIValid() bool
- func (d *AuthorizeRequest) SetResponseTypeHandled(name string)
- type AuthorizeRequester
- type AuthorizeResponder
- type AuthorizeResponse
- func (a *AuthorizeResponse) AddFragment(key, value string)
- func (a *AuthorizeResponse) AddHeader(key, value string)
- func (a *AuthorizeResponse) AddQuery(key, value string)
- func (a *AuthorizeResponse) GetCode() string
- func (a *AuthorizeResponse) GetFragment() url.Values
- func (a *AuthorizeResponse) GetHeader() http.Header
- func (a *AuthorizeResponse) GetQuery() url.Values
- type BCrypt
- type Client
- type ClientManager
- type DefaultClient
- func (c *DefaultClient) GetGrantTypes() Arguments
- func (c *DefaultClient) GetHashedSecret() []byte
- func (c *DefaultClient) GetID() string
- func (c *DefaultClient) GetRedirectURIs() []string
- func (c *DefaultClient) GetResponseTypes() Arguments
- func (c *DefaultClient) GetScopes() Arguments
- func (c *DefaultClient) IsPublic() bool
- type DefaultSession
- type Fosite
- func (f *Fosite) IntrospectToken(ctx context.Context, token string, tokenType TokenType, session Session, ...) (AccessRequester, error)
- func (f *Fosite) NewAccessRequest(ctx context.Context, r *http.Request, session Session) (AccessRequester, error)
- func (f *Fosite) NewAccessResponse(ctx context.Context, req *http.Request, requester AccessRequester) (AccessResponder, error)
- func (c *Fosite) NewAuthorizeRequest(ctx context.Context, r *http.Request) (AuthorizeRequester, error)
- func (o *Fosite) NewAuthorizeResponse(ctx context.Context, r *http.Request, ar AuthorizeRequester, session Session) (AuthorizeResponder, error)
- func (f *Fosite) NewIntrospectionRequest(ctx context.Context, r *http.Request, session Session) (IntrospectionResponder, error)
- func (f *Fosite) NewRevocationRequest(ctx context.Context, r *http.Request) error
- func (c *Fosite) WriteAccessError(rw http.ResponseWriter, _ AccessRequester, err error)
- func (c *Fosite) WriteAccessResponse(rw http.ResponseWriter, requester AccessRequester, responder AccessResponder)
- func (c *Fosite) WriteAuthorizeError(rw http.ResponseWriter, ar AuthorizeRequester, err error)
- func (c *Fosite) WriteAuthorizeResponse(rw http.ResponseWriter, ar AuthorizeRequester, resp AuthorizeResponder)
- func (f *Fosite) WriteIntrospectionError(rw http.ResponseWriter, err error)
- func (f *Fosite) WriteIntrospectionResponse(rw http.ResponseWriter, r IntrospectionResponder)
- func (f *Fosite) WriteRevocationResponse(rw http.ResponseWriter, err error)
- type Hasher
- type IntrospectionResponder
- type IntrospectionResponse
- type OAuth2Provider
- type RFC6749Error
- type Request
- func (a *Request) AppendRequestedScope(scope string)
- func (a *Request) GetClient() Client
- func (a *Request) GetGrantedScopes() Arguments
- func (a *Request) GetID() string
- func (a *Request) GetRequestForm() url.Values
- func (a *Request) GetRequestedAt() time.Time
- func (a *Request) GetRequestedScopes() Arguments
- func (a *Request) GetSession() Session
- func (a *Request) GrantScope(scope string)
- func (a *Request) Merge(request Requester)
- func (a *Request) SetRequestedScopes(s Arguments)
- func (a *Request) SetSession(session Session)
- type Requester
- type RevocationHandler
- type RevocationHandlers
- type ScopeStrategy
- type Session
- type Storage
- type TokenEndpointHandler
- type TokenEndpointHandlers
- type TokenIntrospectionHandlers
- type TokenIntrospector
- type TokenType
Constants ¶
const MinParameterEntropy = 8
const (
UnknownErrorName = "unknown_error"
)
Variables ¶
var ( ErrRequestForbidden = errors.New("The request is not allowed") ErrInvalidRequest = errors.New("The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed") ErrAccessDenied = errors.New("The resource owner or authorization server denied the request") ErrUnsupportedResponseType = errors.New("The authorization server does not support obtaining a token using this method") ErrInvalidScope = errors.New("The requested scope is invalid, unknown, or malformed") ErrServerError = errors.New("The authorization server encountered an unexpected condition that prevented it from fulfilling the request") ErrUnsupportedGrantType = errors.New("The authorization grant type is not supported by the authorization server") ErrInvalidGrant = errors.New("The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client") ErrInvalidClient = errors.New("Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method)") ErrInvalidState = errors.Errorf("The state is missing or has less than %d characters and is therefore considered too weak", MinParameterEntropy) ErrInsufficientEntropy = errors.Errorf("The request used a security parameter (e.g., anti-replay, anti-csrf) with insufficient entropy (minimum of %d characters)", MinParameterEntropy) ErrMisconfiguration = errors.New("The request failed because of an internal error that is probably caused by misconfiguration") ErrNotFound = errors.New("Could not find the requested resource(s)") ErrInvalidTokenFormat = errors.New("Invalid token format") ErrTokenSignatureMismatch = errors.New("Token signature mismatch") ErrTokenExpired = errors.New("Token expired") ErrScopeNotGranted = errors.New("The token was not granted the requested scope") ErrTokenClaim = errors.New("The token failed validation due to a claim mismatch") ErrInactiveToken = errors.New("Token is inactive because it is malformed, expired or otherwise invalid") )
var ErrUnknownRequest = errors.New("The handler is not responsible for this request.")
Functions ¶
func AccessTokenFromRequest ¶ added in v0.2.0
func GetRedirectURIFromRequestValues ¶
GetRedirectURIFromRequestValues extracts the redirect_uri from values but does not do any sort of validation.
Considered specifications
- https://tools.ietf.org/html/rfc6749#section-3.1 The endpoint URI MAY include an "application/x-www-form-urlencoded" formatted (per Appendix B) query component ([RFC3986] Section 3.4), which MUST be retained when adding additional query parameters.
func HierarchicScopeStrategy ¶ added in v0.2.0
func IsRedirectURISecure ¶
func IsValidRedirectURI ¶
IsValidRedirectURI validates a redirect_uri as specified in:
* https://tools.ietf.org/html/rfc6749#section-3.1.2
- The redirection endpoint URI MUST be an absolute URI as defined by [RFC3986] Section 4.3.
- The endpoint URI MUST NOT include a fragment component.
- https://tools.ietf.org/html/rfc3986#section-4.3 absolute-URI = scheme ":" hier-part [ "?" query ]
- https://tools.ietf.org/html/rfc6819#section-5.1.1
func MatchRedirectURIWithClientRedirectURIs ¶
MatchRedirectURIWithClientRedirectURIs if the given uri is a registered redirect uri. Does not perform uri validation.
Considered specifications
https://tools.ietf.org/html/rfc6749#section-3.1.2.3 If multiple redirection URIs have been registered, if only part of the redirection URI has been registered, or if no redirection URI has been registered, the client MUST include a redirection URI with the authorization request using the "redirect_uri" request parameter.
When a redirection URI is included in an authorization request, the authorization server MUST compare and match the value received against at least one of the registered redirection URIs (or URI components) as defined in [RFC3986] Section 6, if any redirection URIs were registered. If the client registration included the full redirection URI, the authorization server MUST compare the two URIs using simple string comparison as defined in [RFC3986] Section 6.2.1.
* https://tools.ietf.org/html/rfc6819#section-4.4.1.7
- The authorization server may also enforce the usage and validation of pre-registered redirect URIs (see Section 5.2.3.5). This will allow for early recognition of authorization "code" disclosure to counterfeit clients.
- The attacker will need to use another redirect URI for its authorization process rather than the target web site because it needs to intercept the flow. So, if the authorization server associates the authorization "code" with the redirect URI of a particular end-user authorization and validates this redirect URI with the redirect URI passed to the token's endpoint, such an attack is detected (see Section 5.2.4.5).
func NewContext ¶
func StringInSlice ¶
StringInSlice returns true if needle exists in haystack
Types ¶
type AccessRequest ¶
type AccessRequest struct { GrantTypes Arguments `json:"grantTypes" gorethink:"grantTypes"` HandledGrantType Arguments `json:"handledGrantType" gorethink:"handledGrantType"` Request }
func NewAccessRequest ¶
func NewAccessRequest(session Session) *AccessRequest
func (*AccessRequest) GetGrantTypes ¶
func (a *AccessRequest) GetGrantTypes() Arguments
type AccessRequester ¶
type AccessRequester interface { // GetGrantType returns the requests grant type. GetGrantTypes() (grantTypes Arguments) Requester }
AccessRequester is a token endpoint's request context.
type AccessResponder ¶
type AccessResponder interface { // SetExtra sets a key value pair for the access response. SetExtra(key string, value interface{}) // GetExtra returns a key's value. GetExtra(key string) interface{} SetExpiresIn(time.Duration) SetScopes(scopes Arguments) // SetAccessToken sets the responses mandatory access token. SetAccessToken(token string) // SetTokenType set's the responses mandatory token type SetTokenType(tokenType string) // SetAccessToken returns the responses access token. GetAccessToken() (token string) // GetTokenType returns the responses token type. GetTokenType() (token string) // ToMap converts the response to a map. ToMap() map[string]interface{} }
AccessResponder is a token endpoint's response.
func NewAccessResponse ¶
func NewAccessResponse() AccessResponder
type AccessResponse ¶
func (*AccessResponse) GetAccessToken ¶
func (a *AccessResponse) GetAccessToken() string
func (*AccessResponse) GetExtra ¶
func (a *AccessResponse) GetExtra(key string) interface{}
func (*AccessResponse) GetTokenType ¶
func (a *AccessResponse) GetTokenType() string
func (*AccessResponse) SetAccessToken ¶
func (a *AccessResponse) SetAccessToken(token string)
func (*AccessResponse) SetExpiresIn ¶
func (a *AccessResponse) SetExpiresIn(expiresIn time.Duration)
func (*AccessResponse) SetExtra ¶
func (a *AccessResponse) SetExtra(key string, value interface{})
func (*AccessResponse) SetScopes ¶
func (a *AccessResponse) SetScopes(scopes Arguments)
func (*AccessResponse) SetTokenType ¶
func (a *AccessResponse) SetTokenType(name string)
func (*AccessResponse) ToMap ¶
func (a *AccessResponse) ToMap() map[string]interface{}
type AuthorizeEndpointHandler ¶
type AuthorizeEndpointHandler interface { // HandleAuthorizeRequest handles an authorize endpoint request. To extend the handler's capabilities, the http request // is passed along, if further information retrieval is required. If the handler feels that he is not responsible for // the authorize request, he must return nil and NOT modify session nor responder neither requester. // // The following spec is a good example of what HandleAuthorizeRequest should do. // * https://tools.ietf.org/html/rfc6749#section-3.1.1 // response_type REQUIRED. // The value MUST be one of "code" for requesting an // authorization code as described by Section 4.1.1, "token" for // requesting an access token (implicit grant) as described by // Section 4.2.1, or a registered extension value as described by Section 8.4. HandleAuthorizeEndpointRequest(ctx context.Context, req *http.Request, requester AuthorizeRequester, responder AuthorizeResponder) error }
type AuthorizeEndpointHandlers ¶
type AuthorizeEndpointHandlers []AuthorizeEndpointHandler
AuthorizeEndpointHandlers is a list of AuthorizeEndpointHandler
func (*AuthorizeEndpointHandlers) Append ¶
func (a *AuthorizeEndpointHandlers) Append(h AuthorizeEndpointHandler)
Append adds an AuthorizeEndpointHandler to this list. Ignores duplicates based on reflect.TypeOf.
type AuthorizeRequest ¶
type AuthorizeRequest struct { ResponseTypes Arguments `json:"responseTypes" gorethink:"responseTypes"` RedirectURI *url.URL `json:"redirectUri" gorethink:"redirectUri"` State string `json:"state" gorethink:"state"` HandledResponseTypes Arguments `json:"handledResponseTypes" gorethink:"handledResponseTypes"` Request }
AuthorizeRequest is an implementation of AuthorizeRequester
func NewAuthorizeRequest ¶
func NewAuthorizeRequest() *AuthorizeRequest
func (*AuthorizeRequest) DidHandleAllResponseTypes ¶
func (d *AuthorizeRequest) DidHandleAllResponseTypes() bool
func (*AuthorizeRequest) GetRedirectURI ¶
func (d *AuthorizeRequest) GetRedirectURI() *url.URL
func (*AuthorizeRequest) GetResponseTypes ¶
func (d *AuthorizeRequest) GetResponseTypes() Arguments
func (*AuthorizeRequest) GetState ¶
func (d *AuthorizeRequest) GetState() string
func (*AuthorizeRequest) IsRedirectURIValid ¶
func (d *AuthorizeRequest) IsRedirectURIValid() bool
func (*AuthorizeRequest) SetResponseTypeHandled ¶
func (d *AuthorizeRequest) SetResponseTypeHandled(name string)
type AuthorizeRequester ¶
type AuthorizeRequester interface { // GetResponseTypes returns the requested response types GetResponseTypes() (responseTypes Arguments) // SetResponseTypeHandled marks a response_type (e.g. token or code) as handled indicating that the response type // is supported. SetResponseTypeHandled(responseType string) // DidHandleAllResponseTypes returns if all requested response types have been handled correctly DidHandleAllResponseTypes() (didHandle bool) // GetRedirectURI returns the requested redirect URI GetRedirectURI() (redirectURL *url.URL) // IsRedirectURIValid returns false if the redirect is not rfc-conform (i.e. missing client, not on white list, // or malformed) IsRedirectURIValid() (isValid bool) // GetState returns the request's state. GetState() (state string) Requester }
AuthorizeRequester is an authorize endpoint's request context.
type AuthorizeResponder ¶
type AuthorizeResponder interface { // GetCode returns the response's authorize code if set. GetCode() string // GetHeader returns the response's header GetHeader() (header http.Header) // AddHeader adds an header key value pair to the response AddHeader(key, value string) // GetQuery returns the response's query GetQuery() (query url.Values) // AddQuery adds an url query key value pair to the response AddQuery(key, value string) // GetHeader returns the response's url fragments GetFragment() (fragment url.Values) // AddHeader adds a key value pair to the response's url fragment AddFragment(key, value string) }
AuthorizeResponder is an authorization endpoint's response.
type AuthorizeResponse ¶
type AuthorizeResponse struct { Header http.Header Query url.Values Fragment url.Values // contains filtered or unexported fields }
AuthorizeResponse is an implementation of AuthorizeResponder
func NewAuthorizeResponse ¶
func NewAuthorizeResponse() *AuthorizeResponse
func (*AuthorizeResponse) AddFragment ¶
func (a *AuthorizeResponse) AddFragment(key, value string)
func (*AuthorizeResponse) AddHeader ¶
func (a *AuthorizeResponse) AddHeader(key, value string)
func (*AuthorizeResponse) AddQuery ¶
func (a *AuthorizeResponse) AddQuery(key, value string)
func (*AuthorizeResponse) GetCode ¶
func (a *AuthorizeResponse) GetCode() string
func (*AuthorizeResponse) GetFragment ¶
func (a *AuthorizeResponse) GetFragment() url.Values
func (*AuthorizeResponse) GetHeader ¶
func (a *AuthorizeResponse) GetHeader() http.Header
func (*AuthorizeResponse) GetQuery ¶
func (a *AuthorizeResponse) GetQuery() url.Values
type BCrypt ¶ added in v0.4.0
type BCrypt struct {
WorkFactor int
}
BCrypt implements the Hasher interface by using BCrypt.
type Client ¶
type Client interface { // GetID returns the client ID. GetID() string // GetHashedSecret returns the hashed secret as it is stored in the store. GetHashedSecret() []byte // Returns the client's allowed redirect URIs. GetRedirectURIs() []string // Returns the client's allowed grant types. GetGrantTypes() Arguments // Returns the client's allowed response types. GetResponseTypes() Arguments // Returns the scopes this client is allowed to request. GetScopes() Arguments // IsPublic returns true, if this client is marked as public. IsPublic() bool }
Client represents a client or an app.
type ClientManager ¶
type ClientManager interface { // GetClient loads the client by its ID or returns an error // if the client does not exist or another error occurred. GetClient(id string) (Client, error) }
ClientManager defines the (persistent) manager interface for clients.
type DefaultClient ¶
type DefaultClient struct { ID string `json:"id"` Secret []byte `json:"client_secret,omitempty"` RedirectURIs []string `json:"redirect_uris"` GrantTypes []string `json:"grant_types"` ResponseTypes []string `json:"response_types"` Scopes []string `json:"scopes"` Public bool `json:"public"` }
DefaultClient is a simple default implementation of the Client interface.
func (*DefaultClient) GetGrantTypes ¶
func (c *DefaultClient) GetGrantTypes() Arguments
func (*DefaultClient) GetHashedSecret ¶
func (c *DefaultClient) GetHashedSecret() []byte
func (*DefaultClient) GetID ¶
func (c *DefaultClient) GetID() string
func (*DefaultClient) GetRedirectURIs ¶
func (c *DefaultClient) GetRedirectURIs() []string
func (*DefaultClient) GetResponseTypes ¶
func (c *DefaultClient) GetResponseTypes() Arguments
func (*DefaultClient) GetScopes ¶ added in v0.2.0
func (c *DefaultClient) GetScopes() Arguments
func (*DefaultClient) IsPublic ¶ added in v0.4.0
func (c *DefaultClient) IsPublic() bool
type DefaultSession ¶ added in v0.5.0
DefaultSession is a default implementation of the session interface.
func (*DefaultSession) Clone ¶ added in v0.6.0
func (s *DefaultSession) Clone() Session
func (*DefaultSession) GetExpiresAt ¶ added in v0.5.0
func (s *DefaultSession) GetExpiresAt(key TokenType) time.Time
func (*DefaultSession) GetSubject ¶ added in v0.5.0
func (s *DefaultSession) GetSubject() string
func (*DefaultSession) GetUsername ¶ added in v0.5.0
func (s *DefaultSession) GetUsername() string
func (*DefaultSession) SetExpiresAt ¶ added in v0.5.0
func (s *DefaultSession) SetExpiresAt(key TokenType, exp time.Time)
type Fosite ¶
type Fosite struct { Store Storage AuthorizeEndpointHandlers AuthorizeEndpointHandlers TokenEndpointHandlers TokenEndpointHandlers TokenIntrospectionHandlers TokenIntrospectionHandlers RevocationHandlers RevocationHandlers Hasher Hasher ScopeStrategy ScopeStrategy }
Fosite implements OAuth2Provider.
func (*Fosite) IntrospectToken ¶ added in v0.4.0
func (*Fosite) NewAccessRequest ¶
func (f *Fosite) NewAccessRequest(ctx context.Context, r *http.Request, session Session) (AccessRequester, error)
Implements
- https://tools.ietf.org/html/rfc6749#section-2.3.1 Clients in possession of a client password MAY use the HTTP Basic authentication scheme as defined in [RFC2617] to authenticate with the authorization server. The client identifier is encoded using the "application/x-www-form-urlencoded" encoding algorithm per Appendix B, and the encoded value is used as the username; the client password is encoded using the same algorithm and used as the password. The authorization server MUST support the HTTP Basic authentication scheme for authenticating clients that were issued a client password. Including the client credentials in the request-body using the two parameters is NOT RECOMMENDED and SHOULD be limited to clients unable to directly utilize the HTTP Basic authentication scheme (or other password-based HTTP authentication schemes). The parameters can only be transmitted in the request-body and MUST NOT be included in the request URI.
- https://tools.ietf.org/html/rfc6749#section-3.2.1
- Confidential clients or other clients issued client credentials MUST authenticate with the authorization server as described in Section 2.3 when making requests to the token endpoint.
- If the client type is confidential or the client was issued client credentials (or assigned other authentication requirements), the client MUST authenticate with the authorization server as described in Section 3.2.1.
func (*Fosite) NewAccessResponse ¶
func (f *Fosite) NewAccessResponse(ctx context.Context, req *http.Request, requester AccessRequester) (AccessResponder, error)
func (*Fosite) NewAuthorizeRequest ¶
func (*Fosite) NewAuthorizeResponse ¶
func (o *Fosite) NewAuthorizeResponse(ctx context.Context, r *http.Request, ar AuthorizeRequester, session Session) (AuthorizeResponder, error)
func (*Fosite) NewIntrospectionRequest ¶ added in v0.4.0
func (f *Fosite) NewIntrospectionRequest(ctx context.Context, r *http.Request, session Session) (IntrospectionResponder, error)
NewIntrospectionRequest initiates token introspection as defined in https://tools.ietf.org/search/rfc7662#section-2.1
The protected resource calls the introspection endpoint using an HTTP POST [RFC7231] request with parameters sent as "application/x-www-form-urlencoded" data as defined in [W3C.REC-html5-20141028]. The protected resource sends a parameter representing the token along with optional parameters representing additional context that is known by the protected resource to aid the authorization server in its response.
* token REQUIRED. The string value of the token. For access tokens, this is the "access_token" value returned from the token endpoint defined in OAuth 2.0 [RFC6749], Section 5.1. For refresh tokens, this is the "refresh_token" value returned from the token endpoint as defined in OAuth 2.0 [RFC6749], Section 5.1. Other token types are outside the scope of this specification.
* token_type_hint OPTIONAL. A hint about the type of the token submitted for introspection. The protected resource MAY pass this parameter to help the authorization server optimize the token lookup. If the server is unable to locate the token using the given hint, it MUST extend its search across all of its supported token types. An authorization server MAY ignore this parameter, particularly if it is able to detect the token type automatically. Values for this field are defined in the "OAuth Token Type Hints" registry defined in OAuth Token Revocation [RFC7009].
The introspection endpoint MAY accept other OPTIONAL parameters to provide further context to the query. For instance, an authorization server may desire to know the IP address of the client accessing the protected resource to determine if the correct client is likely to be presenting the token. The definition of this or any other parameters are outside the scope of this specification, to be defined by service documentation or extensions to this specification. If the authorization server is unable to determine the state of the token without additional information, it SHOULD return an introspection response indicating the token is not active as described in Section 2.2.
To prevent token scanning attacks, the endpoint MUST also require some form of authorization to access this endpoint, such as client authentication as described in OAuth 2.0 [RFC6749] or a separate OAuth 2.0 access token such as the bearer token described in OAuth 2.0 Bearer Token Usage [RFC6750]. The methods of managing and validating these authentication credentials are out of scope of this specification.
For example, the following shows a protected resource calling the token introspection endpoint to query about an OAuth 2.0 bearer token. The protected resource is using a separate OAuth 2.0 bearer token to authorize this call.
The following is a non-normative example request:
POST /introspect HTTP/1.1 Host: server.example.com Accept: application/json Content-Type: application/x-www-form-urlencoded Authorization: Bearer 23410913-abewfq.123483 token=2YotnFZFEjr1zCsicMWpAA
In this example, the protected resource uses a client identifier and client secret to authenticate itself to the introspection endpoint. The protected resource also sends a token type hint indicating that it is inquiring about an access token.
The following is a non-normative example request:
POST /introspect HTTP/1.1 Host: server.example.com Accept: application/json Content-Type: application/x-www-form-urlencoded Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW token=mF_9.B5f-4.1JqM&token_type_hint=access_token
func (*Fosite) NewRevocationRequest ¶ added in v0.4.0
NewRevocationRequest handles incoming token revocation requests and validates various parameters as specified in: https://tools.ietf.org/html/rfc7009#section-2.1
The authorization server first validates the client credentials (in case of a confidential client) and then verifies whether the token was issued to the client making the revocation request. If this validation fails, the request is refused and the client is informed of the error by the authorization server as described below.
In the next step, the authorization server invalidates the token. The invalidation takes place immediately, and the token cannot be used again after the revocation.
* https://tools.ietf.org/html/rfc7009#section-2.2 An invalid token type hint value is ignored by the authorization server and does not influence the revocation response.
func (*Fosite) WriteAccessError ¶
func (c *Fosite) WriteAccessError(rw http.ResponseWriter, _ AccessRequester, err error)
func (*Fosite) WriteAccessResponse ¶
func (c *Fosite) WriteAccessResponse(rw http.ResponseWriter, requester AccessRequester, responder AccessResponder)
func (*Fosite) WriteAuthorizeError ¶
func (c *Fosite) WriteAuthorizeError(rw http.ResponseWriter, ar AuthorizeRequester, err error)
func (*Fosite) WriteAuthorizeResponse ¶
func (c *Fosite) WriteAuthorizeResponse(rw http.ResponseWriter, ar AuthorizeRequester, resp AuthorizeResponder)
func (*Fosite) WriteIntrospectionError ¶ added in v0.4.0
func (f *Fosite) WriteIntrospectionError(rw http.ResponseWriter, err error)
WriteIntrospectionError responds with token metadata discovered by token introspection as defined in https://tools.ietf.org/search/rfc7662#section-2.2
If the protected resource uses OAuth 2.0 client credentials to authenticate to the introspection endpoint and its credentials are invalid, the authorization server responds with an HTTP 401 (Unauthorized) as described in Section 5.2 of OAuth 2.0 [RFC6749].
If the protected resource uses an OAuth 2.0 bearer token to authorize its call to the introspection endpoint and the token used for authorization does not contain sufficient privileges or is otherwise invalid for this request, the authorization server responds with an HTTP 401 code as described in Section 3 of OAuth 2.0 Bearer Token Usage [RFC6750].
Note that a properly formed and authorized query for an inactive or otherwise invalid token (or a token the protected resource is not allowed to know about) is not considered an error response by this specification. In these cases, the authorization server MUST instead respond with an introspection response with the "active" field set to "false" as described in Section 2.2.
func (*Fosite) WriteIntrospectionResponse ¶ added in v0.4.0
func (f *Fosite) WriteIntrospectionResponse(rw http.ResponseWriter, r IntrospectionResponder)
WriteIntrospectionResponse responds with an error if token introspection failed as defined in https://tools.ietf.org/search/rfc7662#section-2.3
The server responds with a JSON object [RFC7159] in "application/ json" format with the following top-level members.
* active REQUIRED. Boolean indicator of whether or not the presented token is currently active. The specifics of a token's "active" state will vary depending on the implementation of the authorization server and the information it keeps about its tokens, but a "true" value return for the "active" property will generally indicate that a given token has been issued by this authorization server, has not been revoked by the resource owner, and is within its given time window of validity (e.g., after its issuance time and before its expiration time). See Section 4 for information on implementation of such checks.
* scope OPTIONAL. A JSON string containing a space-separated list of scopes associated with this token, in the format described in Section 3.3 of OAuth 2.0 [RFC6749].
* client_id OPTIONAL. Client identifier for the OAuth 2.0 client that requested this token.
* username OPTIONAL. Human-readable identifier for the resource owner who authorized this token.
* token_type OPTIONAL. Type of the token as defined in Section 5.1 of OAuth 2.0 [RFC6749].
* exp OPTIONAL. Integer timestamp, measured in the number of seconds since January 1 1970 UTC, indicating when this token will expire, as defined in JWT [RFC7519].
* iat OPTIONAL. Integer timestamp, measured in the number of seconds since January 1 1970 UTC, indicating when this token was originally issued, as defined in JWT [RFC7519].
* nbf OPTIONAL. Integer timestamp, measured in the number of seconds since January 1 1970 UTC, indicating when this token is not to be used before, as defined in JWT [RFC7519].
* sub OPTIONAL. Subject of the token, as defined in JWT [RFC7519]. Usually a machine-readable identifier of the resource owner who authorized this token.
* aud OPTIONAL. Service-specific string identifier or list of string identifiers representing the intended audience for this token, as defined in JWT [RFC7519].
* iss OPTIONAL. String representing the issuer of this token, as defined in JWT [RFC7519].
* jti OPTIONAL. String identifier for the token, as defined in JWT [RFC7519].
Specific implementations MAY extend this structure with their own service-specific response names as top-level members of this JSON object. Response names intended to be used across domains MUST be registered in the "OAuth Token Introspection Response" registry defined in Section 3.1.
The authorization server MAY respond differently to different protected resources making the same request. For instance, an authorization server MAY limit which scopes from a given token are returned for each protected resource to prevent a protected resource from learning more about the larger network than is necessary for its operation.
The response MAY be cached by the protected resource to improve performance and reduce load on the introspection endpoint, but at the cost of liveness of the information used by the protected resource to make authorization decisions. See Section 4 for more information regarding the trade off when the response is cached.
For example, the following response contains a set of information about an active token:
The following is a non-normative example response:
HTTP/1.1 200 OK Content-Type: application/json { "active": true, "client_id": "l238j323ds-23ij4", "username": "jdoe", "scope": "read write dolphin", "sub": "Z5O3upPC88QrAjx00dis", "aud": "https://protected.example.net/resource", "iss": "https://server.example.com/", "exp": 1419356238, "iat": 1419350238, "extension_field": "twenty-seven" }
If the introspection call is properly authorized but the token is not active, does not exist on this server, or the protected resource is not allowed to introspect this particular token, then the authorization server MUST return an introspection response with the "active" field set to "false". Note that to avoid disclosing too much of the authorization server's state to a third party, the authorization server SHOULD NOT include any additional information about an inactive token, including why the token is inactive.
The following is a non-normative example response for a token that has been revoked or is otherwise invalid:
HTTP/1.1 200 OK Content-Type: application/json { "active": false }
func (*Fosite) WriteRevocationResponse ¶ added in v0.4.0
func (f *Fosite) WriteRevocationResponse(rw http.ResponseWriter, err error)
WriteRevocationResponse writes a token revocation response as specified in: https://tools.ietf.org/html/rfc7009#section-2.2
The authorization server responds with HTTP status code 200 if the token has been revoked successfully or if the client submitted an invalid token.
Note: invalid tokens do not cause an error response since the client cannot handle such an error in a reasonable way. Moreover, the purpose of the revocation request, invalidating the particular token, is already achieved.
type Hasher ¶ added in v0.4.0
type Hasher interface { // Compare compares data with a hash and returns an error // if the two do not match. Compare(hash, data []byte) error // Hash creates a hash from data or returns an error. Hash(data []byte) ([]byte, error) }
Hasher defines how a oauth2-compatible hasher should look like.
type IntrospectionResponder ¶ added in v0.4.0
type IntrospectionResponder interface { // IsActive returns true if the introspected token is active and false otherwise. IsActive() bool // AccessRequester returns nil when IsActive() is false and the original access request object otherwise. GetAccessRequester() AccessRequester }
IntrospectionResponse is the response object that will be returned when token introspection was successful, for example when the client is allowed to perform token introspection. Refer to https://tools.ietf.org/search/rfc7662#section-2.2 for more details.
type IntrospectionResponse ¶ added in v0.4.0
type IntrospectionResponse struct { Active bool `json:"active"` AccessRequester AccessRequester `json:",extra"` }
func (*IntrospectionResponse) GetAccessRequester ¶ added in v0.4.0
func (r *IntrospectionResponse) GetAccessRequester() AccessRequester
func (*IntrospectionResponse) IsActive ¶ added in v0.4.0
func (r *IntrospectionResponse) IsActive() bool
type OAuth2Provider ¶
type OAuth2Provider interface { // NewAuthorizeRequest returns an AuthorizeRequest. // // The following specs must be considered in any implementation of this method: // * https://tools.ietf.org/html/rfc6749#section-3.1 // Extension response types MAY contain a space-delimited (%x20) list of // values, where the order of values does not matter (e.g., response // type "a b" is the same as "b a"). The meaning of such composite // response types is defined by their respective specifications. // * https://tools.ietf.org/html/rfc6749#section-3.1.2 // The redirection endpoint URI MUST be an absolute URI as defined by // [RFC3986] Section 4.3. The endpoint URI MAY include an // "application/x-www-form-urlencoded" formatted (per Appendix B) query // component ([RFC3986] Section 3.4), which MUST be retained when adding // additional query parameters. The endpoint URI MUST NOT include a // fragment component. // * https://tools.ietf.org/html/rfc6749#section-3.1.2.2 (everything MUST be implemented) NewAuthorizeRequest(ctx context.Context, req *http.Request) (AuthorizeRequester, error) // NewAuthorizeResponse iterates through all response type handlers and returns their result or // ErrUnsupportedResponseType if none of the handler's were able to handle it. // // The following specs must be considered in any implementation of this method: // * https://tools.ietf.org/html/rfc6749#section-3.1.1 // Extension response types MAY contain a space-delimited (%x20) list of // values, where the order of values does not matter (e.g., response // type "a b" is the same as "b a"). The meaning of such composite // response types is defined by their respective specifications. // If an authorization request is missing the "response_type" parameter, // or if the response type is not understood, the authorization server // MUST return an error response as described in Section 4.1.2.1. NewAuthorizeResponse(ctx context.Context, req *http.Request, requester AuthorizeRequester, session Session) (AuthorizeResponder, error) // WriteAuthorizeError returns the error codes to the redirection endpoint or shows the error to the user, if no valid // redirect uri was given. Implements rfc6749#section-4.1.2.1 // // The following specs must be considered in any implementation of this method: // * https://tools.ietf.org/html/rfc6749#section-3.1.2 // The redirection endpoint URI MUST be an absolute URI as defined by // [RFC3986] Section 4.3. The endpoint URI MAY include an // "application/x-www-form-urlencoded" formatted (per Appendix B) query // component ([RFC3986] Section 3.4), which MUST be retained when adding // additional query parameters. The endpoint URI MUST NOT include a // fragment component. // * https://tools.ietf.org/html/rfc6749#section-4.1.2.1 (everything) // * https://tools.ietf.org/html/rfc6749#section-3.1.2.2 (everything MUST be implemented) WriteAuthorizeError(rw http.ResponseWriter, requester AuthorizeRequester, err error) // WriteAuthorizeResponse persists the AuthorizeSession in the store and redirects the user agent to the provided // redirect url or returns an error if storage failed. // // The following specs must be considered in any implementation of this method: // * https://tools.ietf.org/html/rfc6749#rfc6749#section-4.1.2.1 // After completing its interaction with the resource owner, the // authorization server directs the resource owner's user-agent back to // the client. The authorization server redirects the user-agent to the // client's redirection endpoint previously established with the // authorization server during the client registration process or when // making the authorization request. // * https://tools.ietf.org/html/rfc6749#section-3.1.2.2 (everything MUST be implemented) WriteAuthorizeResponse(rw http.ResponseWriter, requester AuthorizeRequester, responder AuthorizeResponder) // NewAccessRequest creates a new access request object and validates // various parameters. // // The following specs must be considered in any implementation of this method: // * https://tools.ietf.org/html/rfc6749#section-3.2 (everything) // * https://tools.ietf.org/html/rfc6749#section-3.2.1 (everything) // // Furthermore the registered handlers should implement their specs accordingly. NewAccessRequest(ctx context.Context, req *http.Request, session Session) (AccessRequester, error) // NewAccessResponse creates a new access response and validates that access_token and token_type are set. // // The following specs must be considered in any implementation of this method: // https://tools.ietf.org/html/rfc6749#section-5.1 NewAccessResponse(ctx context.Context, req *http.Request, requester AccessRequester) (AccessResponder, error) // WriteAccessError writes an access request error response. // // The following specs must be considered in any implementation of this method: // * https://tools.ietf.org/html/rfc6749#section-5.2 (everything) WriteAccessError(rw http.ResponseWriter, requester AccessRequester, err error) // WriteAccessResponse writes the access response. // // The following specs must be considered in any implementation of this method: // https://tools.ietf.org/html/rfc6749#section-5.1 WriteAccessResponse(rw http.ResponseWriter, requester AccessRequester, responder AccessResponder) // NewRevocationRequest handles incoming token revocation requests and validates various parameters. // // The following specs must be considered in any implementation of this method: // https://tools.ietf.org/html/rfc7009#section-2.1 NewRevocationRequest(ctx context.Context, r *http.Request) error // WriteRevocationResponse writes the revoke response. // // The following specs must be considered in any implementation of this method: // https://tools.ietf.org/html/rfc7009#section-2.2 WriteRevocationResponse(rw http.ResponseWriter, err error) // IntrospectToken returns token metadata, if the token is valid. Tokens generated by the authorization endpoint, // such as the authorization code, can not be introspected. IntrospectToken(ctx context.Context, token string, tokenType TokenType, session Session, scope ...string) (AccessRequester, error) // NewIntrospectionRequest initiates token introspection as defined in // https://tools.ietf.org/search/rfc7662#section-2.1 NewIntrospectionRequest(ctx context.Context, r *http.Request, session Session) (IntrospectionResponder, error) // WriteIntrospectionError responds with an error if token introspection failed as defined in // https://tools.ietf.org/search/rfc7662#section-2.3 WriteIntrospectionError(rw http.ResponseWriter, err error) // WriteIntrospectionResponse responds with token metadata discovered by token introspection as defined in // https://tools.ietf.org/search/rfc7662#section-2.2 WriteIntrospectionResponse(rw http.ResponseWriter, r IntrospectionResponder) }
OAuth2Provider is an interface that enables you to write OAuth2 handlers with only a few lines of code. Check fosite.Fosite for an implementation of this interface.
type RFC6749Error ¶
type RFC6749Error struct { Name string `json:"error"` Description string `json:"error_description"` Hint string `json:"-"` Code int `json:"statusCode"` Debug string `json:"-"` }
func ErrorToRFC6749Error ¶
func ErrorToRFC6749Error(err error) *RFC6749Error
func (*RFC6749Error) Details ¶ added in v0.7.0
func (e *RFC6749Error) Details() []map[string]interface{}
func (*RFC6749Error) Error ¶ added in v0.7.0
func (e *RFC6749Error) Error() string
func (*RFC6749Error) Reason ¶ added in v0.7.0
func (e *RFC6749Error) Reason() string
func (*RFC6749Error) RequestID ¶ added in v0.7.0
func (e *RFC6749Error) RequestID() string
func (*RFC6749Error) Status ¶ added in v0.7.0
func (e *RFC6749Error) Status() string
func (*RFC6749Error) StatusCode ¶
func (e *RFC6749Error) StatusCode() int
type Request ¶
type Request struct { ID string `json:"id" gorethink:"id"` RequestedAt time.Time `json:"requestedAt" gorethink:"requestedAt"` Client Client `json:"client" gorethink:"client"` Scopes Arguments `json:"scopes" gorethink:"scopes"` GrantedScopes Arguments `json:"grantedScopes" gorethink:"grantedScopes"` Form url.Values `json:"form" gorethink:"form"` Session Session `json:"session" gorethink:"session"` }
Request is an implementation of Requester
func NewRequest ¶
func NewRequest() *Request
func (*Request) AppendRequestedScope ¶ added in v0.2.0
func (*Request) GetGrantedScopes ¶
func (*Request) GetRequestForm ¶
func (*Request) GetRequestedAt ¶
func (*Request) GetRequestedScopes ¶ added in v0.2.0
func (*Request) GetSession ¶
func (*Request) GrantScope ¶
func (*Request) SetRequestedScopes ¶ added in v0.2.0
func (*Request) SetSession ¶
type Requester ¶
type Requester interface { // GetID returns a unique identifier. GetID() string // GetRequestedAt returns the time the request was created. GetRequestedAt() (requestedAt time.Time) // GetClient returns the requests client. GetClient() (client Client) // GetRequestedScopes returns the request's scopes. GetRequestedScopes() (scopes Arguments) // SetRequestedScopes sets the request's scopes. SetRequestedScopes(scopes Arguments) // AppendRequestedScope appends a scope to the request. AppendRequestedScope(scope string) // GetGrantScopes returns all granted scopes. GetGrantedScopes() (grantedScopes Arguments) // GrantScope marks a request's scope as granted. GrantScope(scope string) // GetSession returns a pointer to the request's session or nil if none is set. GetSession() (session Session) // GetSession sets the request's session pointer. SetSession(session Session) // GetRequestForm returns the request's form input. GetRequestForm() url.Values Merge(requester Requester) }
Requester is an abstract interface for handling requests in Fosite.
type RevocationHandler ¶ added in v0.4.0
type RevocationHandler interface { // RevokeToken handles access and refresh token revocation. RevokeToken(ctx context.Context, token string, tokenType TokenType) error }
RevocationHandler is the interface that allows token revocation for an OAuth2.0 provider. https://tools.ietf.org/html/rfc7009
RevokeToken is invoked after a new token revocation request is parsed.
https://tools.ietf.org/html/rfc7009#section-2.1 If the particular token is a refresh token and the authorization server supports the revocation of access tokens, then the authorization server SHOULD also invalidate all access tokens based on the same authorization grant (see Implementation Note). If the token passed to the request is an access token, the server MAY revoke the respective refresh token as well.
type RevocationHandlers ¶ added in v0.4.0
type RevocationHandlers []RevocationHandler
RevocationHandlers is a list of RevocationHandler
func (*RevocationHandlers) Append ¶ added in v0.4.0
func (t *RevocationHandlers) Append(h RevocationHandler)
Append adds an RevocationHandler to this list. Ignores duplicates based on reflect.TypeOf.
type ScopeStrategy ¶ added in v0.2.0
ScopeStrategy is a strategy for matching scopes.
type Session ¶ added in v0.5.0
type Session interface { // SetExpiresAt sets the expiration time of a token. // // session.SetExpiresAt(fosite.AccessToken, time.Now().Add(time.Hour)) SetExpiresAt(key TokenType, exp time.Time) // SetExpiresAt returns expiration time of a token if set, or time.IsZero() if not. // // session.GetExpiresAt(fosite.AccessToken) GetExpiresAt(key TokenType) time.Time // GetUsername returns the username, if set. This is optional and only used during token introspection. GetUsername() string // GetSubject returns the subject, if set. This is optional and only used during token introspection. GetSubject() string // Clone clones the session. Clone() Session }
Session is an interface that is used to store session data between OAuth2 requests. It can be used to look up when a session expires or what the subject's name was.
type Storage ¶
type Storage interface { ClientManager }
Storage defines fosite's minimal storage interface.
type TokenEndpointHandler ¶
type TokenEndpointHandler interface { // PopulateTokenEndpointResponse is responsible for setting return values and should only be executed if // the handler's HandleTokenEndpointRequest did not return ErrUnknownRequest. PopulateTokenEndpointResponse(ctx context.Context, req *http.Request, requester AccessRequester, responder AccessResponder) error // HandleTokenEndpointRequest handles an authorize request. If the handler is not responsible for handling // the request, this method should return ErrUnknownRequest and otherwise handle the request. HandleTokenEndpointRequest(ctx context.Context, req *http.Request, requester AccessRequester) error }
type TokenEndpointHandlers ¶
type TokenEndpointHandlers []TokenEndpointHandler
TokenEndpointHandlers is a list of TokenEndpointHandler
func (*TokenEndpointHandlers) Append ¶
func (t *TokenEndpointHandlers) Append(h TokenEndpointHandler)
Append adds an TokenEndpointHandler to this list. Ignores duplicates based on reflect.TypeOf.
type TokenIntrospectionHandlers ¶ added in v0.4.0
type TokenIntrospectionHandlers []TokenIntrospector
TokenIntrospectionHandlers is a list of TokenValidator
func (*TokenIntrospectionHandlers) Append ¶ added in v0.4.0
func (t *TokenIntrospectionHandlers) Append(h TokenIntrospector)
Add adds an AccessTokenValidator to this list. Ignores duplicates based on reflect.TypeOf.
type TokenIntrospector ¶ added in v0.4.0
Source Files ¶
- access_error.go
- access_request.go
- access_request_handler.go
- access_response.go
- access_response_writer.go
- access_write.go
- arguments.go
- authorize_error.go
- authorize_helper.go
- authorize_request.go
- authorize_request_handler.go
- authorize_response.go
- authorize_response_writer.go
- authorize_write.go
- client.go
- client_manager.go
- context.go
- errors.go
- fosite.go
- handler.go
- hash.go
- hash_bcrypt.go
- helper.go
- introspect.go
- introspection_request_handler.go
- introspection_response_writer.go
- oauth2.go
- request.go
- revoke_handler.go
- scope_strategy.go
- session.go
- storage.go
Directories ¶
Path | Synopsis |
---|---|
handler
|
|
token
|
|
hmac
Package hmac is the default implementation for generating and validating challenges.
|
Package hmac is the default implementation for generating and validating challenges. |
jwt
Package jwt is able to generate and validate json web tokens.
|
Package jwt is able to generate and validate json web tokens. |