Skip to content

Commit

Permalink
introspection: Decodes of Basic Authorization username/password (#245)
Browse files Browse the repository at this point in the history
Signed-off-by: Dmitry Dolbik <dolbik@gmail.com>
  • Loading branch information
dolbik authored and arekkas committed Jan 25, 2018
1 parent 1ef3041 commit b94312e
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 2 deletions.
13 changes: 12 additions & 1 deletion introspection_request_handler.go
Expand Up @@ -17,6 +17,7 @@ package fosite
import (
"context"
"net/http"
"net/url"
"strings"

"fmt"
Expand Down Expand Up @@ -122,11 +123,21 @@ func (f *Fosite) NewIntrospectionRequest(ctx context.Context, r *http.Request, s
return &IntrospectionResponse{Active: false}, errors.WithStack(ErrRequestUnauthorized.WithDebug("HTTP Authorization header missing.WithDebug(malformed or credentials used are invalid"))
}
} else {
clientID, clientSecret, ok := r.BasicAuth()
id, secret, ok := r.BasicAuth()
if !ok {
return &IntrospectionResponse{Active: false}, errors.WithStack(ErrRequestUnauthorized.WithDebug("HTTP Authorization header missing.WithDebug(malformed or credentials used are invalid"))
}

clientID, err := url.QueryUnescape(id)
if err != nil {
return &IntrospectionResponse{Active: false}, errors.WithStack(ErrRequestUnauthorized.WithDebug("HTTP Authorization header missing.WithDebug(malformed or credentials used are invalid"))
}

clientSecret, err := url.QueryUnescape(secret)
if err != nil {
return &IntrospectionResponse{Active: false}, errors.WithStack(ErrRequestUnauthorized.WithDebug("HTTP Authorization header missing.WithDebug(malformed or credentials used are invalid"))
}

client, err := f.Store.GetClient(ctx, clientID)
if err != nil {
return &IntrospectionResponse{Active: false}, errors.WithStack(ErrRequestUnauthorized.WithDebug("HTTP Authorization header missing.WithDebug(malformed or credentials used are invalid"))
Expand Down
38 changes: 37 additions & 1 deletion introspection_request_handler_test.go
Expand Up @@ -47,7 +47,7 @@ func TestNewIntrospectionRequest(t *testing.T) {
validator := internal.NewMockTokenIntrospector(ctrl)
defer ctrl.Finish()

f := compose.ComposeAllEnabled(new(compose.Config), storage.NewMemoryStore(), []byte{}, nil).(*Fosite)
f := compose.ComposeAllEnabled(new(compose.Config), storage.NewExampleStore(), []byte{}, nil).(*Fosite)
httpreq := &http.Request{
Method: "POST",
Header: http.Header{},
Expand Down Expand Up @@ -104,6 +104,42 @@ func TestNewIntrospectionRequest(t *testing.T) {
},
isActive: true,
},
{
description: "should pass with basic auth if username and password encoded",
setup: func() {
f.TokenIntrospectionHandlers = TokenIntrospectionHandlers{validator}
httpreq = &http.Request{
Method: "POST",
Header: http.Header{
//Basic Authorization with username=encoded:client and password=encoded&password
"Authorization": []string{"Basic ZW5jb2RlZCUzQWNsaWVudDplbmNvZGVkJTI2cGFzc3dvcmQ="},
},
PostForm: url.Values{
"token": []string{"introspect-token"},
},
}
validator.EXPECT().IntrospectToken(nil, "introspect-token", gomock.Any(), gomock.Any(), gomock.Any()).Return(nil)
},
isActive: true,
},
{
description: "should pass with basic auth if username and password not encoded",
setup: func() {
f.TokenIntrospectionHandlers = TokenIntrospectionHandlers{validator}
httpreq = &http.Request{
Method: "POST",
Header: http.Header{
//Basic Authorization with username=my-client and password=foobar
"Authorization": []string{"Basic bXktY2xpZW50OmZvb2Jhcg=="},
},
PostForm: url.Values{
"token": []string{"introspect-token"},
},
}
validator.EXPECT().IntrospectToken(nil, "introspect-token", gomock.Any(), gomock.Any(), gomock.Any()).Return(nil)
},
isActive: true,
},
} {
t.Run(fmt.Sprintf("case=%d", k), func(t *testing.T) {
c.setup()
Expand Down
8 changes: 8 additions & 0 deletions storage/memory.go
Expand Up @@ -65,6 +65,14 @@ func NewExampleStore() *MemoryStore {
GrantTypes: []string{"implicit", "refresh_token", "authorization_code", "password", "client_credentials"},
Scopes: []string{"fosite", "openid", "photos", "offline"},
},
"encoded:client": {
ID: "encoded:client",
Secret: []byte(`$2a$10$A7M8b65dSSKGHF0H2sNkn.9Z0hT8U1Nv6OWPV3teUUaczXkVkxuDS`), // = "encoded&password"
RedirectURIs: []string{"http://localhost:3846/callback"},
ResponseTypes: []string{"id_token", "code", "token"},
GrantTypes: []string{"implicit", "refresh_token", "authorization_code", "password", "client_credentials"},
Scopes: []string{"fosite", "openid", "photos", "offline"},
},
},
Users: map[string]MemoryUserRelation{
"peter": {
Expand Down

0 comments on commit b94312e

Please sign in to comment.