Refactor auth to load token outside wrappers

This commit is contained in:
Ben Toogood
2020-05-14 11:06:22 +01:00
parent 0955671e45
commit 5764519f5b
7 changed files with 91 additions and 192 deletions

View File

@@ -7,6 +7,7 @@ import (
rtime "runtime"
"strings"
"sync"
"time"
"github.com/micro/go-micro/v2/auth"
"github.com/micro/go-micro/v2/client"
@@ -51,12 +52,6 @@ func newService(opts ...Option) Service {
server.WrapHandler(wrapper.AuthHandler(authFn)),
)
// set the client in the service implementations
// options.Auth.Init(auth.WithClient(options.Client))
// options.Registry.Init(registrySrv.WithClient(options.Client))
// options.Runtime.Init(runtime.WithClient(options.Client))
// options.Store.Init(store.WithClient(options.Client))
// set opts
service.opts = options
@@ -119,15 +114,6 @@ func (s *service) Init(opts ...Option) {
// Explicitly set the table name to the service name
name := s.opts.Cmd.App().Name
s.opts.Store.Init(store.Table(name))
// Reset the clients for the micro services, this is done
// previously in newService for micro (since init is never called)
// however it needs to be done again here since for normal go-micro
// services the implementation may have changed by CLI flags.
// s.opts.Auth.Init(auth.WithClient(s.Client()))
// s.opts.Registry.Init(registrySrv.WithClient(s.Client()))
// s.opts.Runtime.Init(runtime.WithClient(s.Client()))
// s.opts.Store.Init(store.WithClient(s.Client()))
})
}
@@ -240,25 +226,70 @@ func (s *service) Run() error {
}
func (s *service) generateAccount() error {
// generate a new auth account for the service
name := fmt.Sprintf("%v-%v", s.Name(), s.Server().Options().Id)
opts := []auth.GenerateOption{
auth.WithType("service"),
auth.WithRoles("service"),
auth.WithNamespace(s.Options().Auth.Options().Namespace),
// extract the account creds from options, these can be set by flags
accID := s.Options().Auth.Options().ID
accSecret := s.Options().Auth.Options().Secret
// if no credentials were provided, generate an account
if len(accID) == 0 || len(accSecret) == 0 {
name := fmt.Sprintf("%v-%v", s.Name(), s.Server().Options().Id)
opts := []auth.GenerateOption{
auth.WithType("service"),
auth.WithRoles("service"),
auth.WithNamespace(s.Options().Auth.Options().Namespace),
}
acc, err := s.Options().Auth.Generate(name, opts...)
if err != nil {
return err
}
logger.Infof("Auth [%v] Authenticated as %v", s.Options().Auth, name)
accID = acc.ID
accSecret = acc.Secret
}
acc, err := s.Options().Auth.Generate(name, opts...)
// generate the first token
token, err := s.Options().Auth.Token(
auth.WithCredentials(accID, accSecret),
auth.WithExpiry(time.Minute*15),
)
if err != nil {
return err
}
// generate a token
token, err := s.Options().Auth.Token(auth.WithCredentials(acc.ID, acc.Secret))
if err != nil {
return err
}
// set the credentials and token in auth options
s.Options().Auth.Init(
auth.ClientToken(token),
auth.Credentials(accID, accSecret),
)
// periodically check to see if the token needs refreshing
go func() {
timer := time.NewTicker(time.Second * 15)
for {
<-timer.C
// don't refresh the token if it's not close to expiring
if token.Expiry.Unix() > time.Now().Add(time.Minute).Unix() {
continue
}
// generate the first token
token, err := s.Options().Auth.Token(
auth.WithCredentials(accID, accSecret),
auth.WithExpiry(time.Minute*15),
)
if err != nil {
logger.Warnf("[Auth] Error refreshing token: %v", err)
continue
}
// set the token
s.Options().Auth.Init(auth.ClientToken(token))
}
}()
s.Options().Auth.Init(auth.ClientToken(token), auth.Credentials(acc.ID, acc.Secret))
logger.Infof("Auth [%v] Authenticated as %v", s.Options().Auth, name)
return nil
}