...

Source file src/github.com/ory/fosite/introspect.go

Documentation: github.com/ory/fosite

     1  /*
     2   * Copyright © 2015-2018 Aeneas Rekkas <aeneas+oss@aeneas.io>
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   *
    16   * @author		Aeneas Rekkas <aeneas+oss@aeneas.io>
    17   * @copyright 	2015-2018 Aeneas Rekkas <aeneas+oss@aeneas.io>
    18   * @license 	Apache-2.0
    19   *
    20   */
    21  
    22  package fosite
    23  
    24  import (
    25  	"context"
    26  	"net/http"
    27  	"strings"
    28  
    29  	"github.com/ory/x/errorsx"
    30  
    31  	"github.com/pkg/errors"
    32  )
    33  
    34  type TokenIntrospector interface {
    35  	IntrospectToken(ctx context.Context, token string, tokenUse TokenUse, accessRequest AccessRequester, scopes []string) (TokenUse, error)
    36  }
    37  
    38  func AccessTokenFromRequest(req *http.Request) string {
    39  	// According to https://tools.ietf.org/html/rfc6750 you can pass tokens through:
    40  	// - Form-Encoded Body Parameter. Recommended, more likely to appear. e.g.: Authorization: Bearer mytoken123
    41  	// - URI Query Parameter e.g. access_token=mytoken123
    42  
    43  	auth := req.Header.Get("Authorization")
    44  	split := strings.SplitN(auth, " ", 2)
    45  	if len(split) != 2 || !strings.EqualFold(split[0], "bearer") {
    46  		// Nothing in Authorization header, try access_token
    47  		// Empty string returned if there's no such parameter
    48  		if err := req.ParseMultipartForm(1 << 20); err != nil && err != http.ErrNotMultipart {
    49  			return ""
    50  		}
    51  		return req.Form.Get("access_token")
    52  	}
    53  
    54  	return split[1]
    55  }
    56  
    57  func (f *Fosite) IntrospectToken(ctx context.Context, token string, tokenUse TokenUse, session Session, scopes ...string) (TokenUse, AccessRequester, error) {
    58  	var found = false
    59  	var foundTokenUse TokenUse = ""
    60  
    61  	ar := NewAccessRequest(session)
    62  	for _, validator := range f.TokenIntrospectionHandlers {
    63  		tu, err := validator.IntrospectToken(ctx, token, tokenUse, ar, scopes)
    64  		if err == nil {
    65  			found = true
    66  			foundTokenUse = tu
    67  		} else if errors.Is(err, ErrUnknownRequest) {
    68  			// do nothing
    69  		} else {
    70  			rfcerr := ErrorToRFC6749Error(err)
    71  			return "", nil, errorsx.WithStack(rfcerr)
    72  		}
    73  	}
    74  
    75  	if !found {
    76  		return "", nil, errorsx.WithStack(ErrRequestUnauthorized.WithHint("Unable to find a suitable validation strategy for the token, thus it is invalid."))
    77  	}
    78  
    79  	return foundTokenUse, ar, nil
    80  }
    81  

View as plain text