Skip to content
This repository has been archived by the owner on Mar 11, 2021. It is now read-only.

Load public keys from auth service instead of hardcoding them in configuration #1623

Merged
merged 9 commits into from
Sep 13, 2017

Conversation

alexeykazakov
Copy link
Contributor

@alexeykazakov alexeykazakov commented Sep 9, 2017

Related to fabric8-services/fabric8-auth#30

Tasks to be completed before it can be merged:

@sbose78
Copy link
Member

sbose78 commented Sep 12, 2017

Looks fine, overall.

@alexeykazakov alexeykazakov changed the title WIP: Load public keys from auth service instead of hardcoding them in configuration Load public keys from auth service instead of hardcoding them in configuration Sep 13, 2017
@alexeykazakov
Copy link
Contributor Author

The PR is ready for review/merge. It's not WIP anymore.

Copy link
Contributor

@xcoulon xcoulon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the changes in token/token.go only.

token/token.go Outdated
if devModeURL != "" {
remoteKeys, err = authtoken.FetchKeys(fmt.Sprintf("%s/protocol/openid-connect/certs", devModeURL))
if err != nil {
log.Error(nil, map[string]interface{}{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do you log the error and return it ? what about wrapping the underlying error with a new message, instead ?

tm.publicKeys = append(tm.publicKeys, &PublicKey{KeyID: remoteKey.KeyID, Key: remoteKey.Key})
log.Info(nil, map[string]interface{}{
"kid": remoteKey.KeyID,
}, "Public key added")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

message should start with lowercase

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's true for error messages in "error" (because they can be combined with other error messages). But here we just printing an info message.

tm.publicKeys = append(tm.publicKeys, &PublicKey{KeyID: remoteKey.KeyID, Key: remoteKey.Key})
log.Info(nil, map[string]interface{}{
"kid": remoteKey.KeyID,
}, "Public key added")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

message should start with lowercase

Copy link
Contributor Author

@alexeykazakov alexeykazakov Sep 13, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's true for error messages inside error (because they can be combined with other error messages). But here we just printing an info message.

token/token.go Outdated
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
return mgm.publicKey, nil
})
remoteKeys, err := authtoken.FetchKeys(config.GetKeysEndpoint())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would it make sense to rename authtoken to authclient in the WIT codebase ?

log.Error(nil, map[string]interface{}{
"keys_url": config.GetKeysEndpoint(),
}, "unable to load public keys from remote service")
return nil, errors.New("unable to load public keys from remote service")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do you log the error and return it ? what about wrapping the underlying error with a new message, instead ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The main reason to log errors inside some function is to add parameters to the error log message which the calling function doesn't care or doesn't have to be aware of.
In this case we are logging keys_uri.

if !token.Valid {
return nil, errors.New("Token not valid")
devModeURL := config.GetKeycloakDevModeURL()
if devModeURL != "" {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aren't you doing the same work as above, with another KC URL ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not exactly. Main difference is that here we are operating with different PublicKey type. (fabric8-auth/PublicKey vs. fabric8-wit/PublicKey). We could re-use this code in both places but it would require to introduce some common interface which can be tricky. So, anyway, it would require us to write more code to re-use this small block in two places. Which doesn't make sense.

}

// NewManagerWithPublicKey returns a new token Manager for handling tokens with the only public key
func NewManagerWithPublicKey(id string, key *rsa.PublicKey) Manager {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this going to be used in dev mode, when the public key for the test realm is loaded from the configuration ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This constructor is used by tests only. The tests that don't care about keys from the test realm.

token/token.go Outdated
kid := token.Header["kid"]
if kid == nil {
log.Error(ctx, map[string]interface{}{}, "There is no 'kid' header in the token")
return nil, errors.New("There is no 'kid' header in the token")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

message should start with lower case

token/token.go Outdated
// ParseToken parses token claims
func (mgm *tokenManager) ParseToken(ctx context.Context, tokenString string) (*TokenClaims, error) {
token, err := jwt.ParseWithClaims(tokenString, &TokenClaims{}, func(token *jwt.Token) (interface{}, error) {
kid := token.Header["kid"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what about kid, found := token.Header["kid"] ?

token/token.go Outdated
}
key := mgm.PublicKey(fmt.Sprintf("%s", kid))
if key == nil {
log.Error(ctx, map[string]interface{}{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same comment as above: what about wrapping the error with the new message ?

Copy link
Contributor Author

@alexeykazakov alexeykazakov Sep 13, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I log it here too just to log the key ID parameter.

Copy link
Member

@sbose78 sbose78 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apart from the minor changes requested by @xcoulon , looks good to me.

@alexeykazakov
Copy link
Contributor Author

I've addressed some @xcoulon comments.

@alexeykazakov alexeykazakov merged commit 08c46ae into fabric8-services:master Sep 13, 2017
@alexeykazakov alexeykazakov deleted the tokenmanager branch September 13, 2017 15:40
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants