go-micro.dev/v5@v5.12.0/auth/jwt/jwt.go (about) 1 package jwt 2 3 import ( 4 "sync" 5 "time" 6 7 jwtToken "github.com/micro/plugins/v5/auth/jwt/token" 8 "go-micro.dev/v5/auth" 9 "go-micro.dev/v5/cmd" 10 ) 11 12 func init() { 13 cmd.DefaultAuths["jwt"] = NewAuth 14 } 15 16 // NewAuth returns a new instance of the Auth service. 17 func NewAuth(opts ...auth.Option) auth.Auth { 18 j := new(jwt) 19 j.Init(opts...) 20 return j 21 } 22 23 func NewRules() auth.Rules { 24 return new(jwtRules) 25 } 26 27 type jwt struct { 28 sync.Mutex 29 options auth.Options 30 jwt jwtToken.Provider 31 } 32 33 type jwtRules struct { 34 sync.Mutex 35 rules []*auth.Rule 36 } 37 38 func (j *jwt) String() string { 39 return "jwt" 40 } 41 42 func (j *jwt) Init(opts ...auth.Option) { 43 j.Lock() 44 defer j.Unlock() 45 46 for _, o := range opts { 47 o(&j.options) 48 } 49 50 j.jwt = jwtToken.New( 51 jwtToken.WithPrivateKey(j.options.PrivateKey), 52 jwtToken.WithPublicKey(j.options.PublicKey), 53 ) 54 } 55 56 func (j *jwt) Options() auth.Options { 57 j.Lock() 58 defer j.Unlock() 59 return j.options 60 } 61 62 func (j *jwt) Generate(id string, opts ...auth.GenerateOption) (*auth.Account, error) { 63 options := auth.NewGenerateOptions(opts...) 64 account := &auth.Account{ 65 ID: id, 66 Type: options.Type, 67 Scopes: options.Scopes, 68 Metadata: options.Metadata, 69 Issuer: j.Options().Namespace, 70 } 71 72 // generate a JWT secret which can be provided to the Token() method 73 // and exchanged for an access token 74 secret, err := j.jwt.Generate(account) 75 if err != nil { 76 return nil, err 77 } 78 account.Secret = secret.Token 79 80 // return the account 81 return account, nil 82 } 83 84 func (j *jwtRules) Grant(rule *auth.Rule) error { 85 j.Lock() 86 defer j.Unlock() 87 j.rules = append(j.rules, rule) 88 return nil 89 } 90 91 func (j *jwtRules) Revoke(rule *auth.Rule) error { 92 j.Lock() 93 defer j.Unlock() 94 95 rules := make([]*auth.Rule, 0, len(j.rules)) 96 for _, r := range j.rules { 97 if r.ID != rule.ID { 98 rules = append(rules, r) 99 } 100 } 101 102 j.rules = rules 103 return nil 104 } 105 106 func (j *jwtRules) Verify(acc *auth.Account, res *auth.Resource, opts ...auth.VerifyOption) error { 107 j.Lock() 108 defer j.Unlock() 109 110 var options auth.VerifyOptions 111 for _, o := range opts { 112 o(&options) 113 } 114 115 return auth.Verify(j.rules, acc, res) 116 } 117 118 func (j *jwtRules) List(opts ...auth.ListOption) ([]*auth.Rule, error) { 119 j.Lock() 120 defer j.Unlock() 121 return j.rules, nil 122 } 123 124 func (j *jwt) Inspect(token string) (*auth.Account, error) { 125 return j.jwt.Inspect(token) 126 } 127 128 func (j *jwt) Token(opts ...auth.TokenOption) (*auth.Token, error) { 129 options := auth.NewTokenOptions(opts...) 130 131 secret := options.RefreshToken 132 if len(options.Secret) > 0 { 133 secret = options.Secret 134 } 135 136 account, err := j.jwt.Inspect(secret) 137 if err != nil { 138 return nil, err 139 } 140 141 access, err := j.jwt.Generate(account, jwtToken.WithExpiry(options.Expiry)) 142 if err != nil { 143 return nil, err 144 } 145 146 refresh, err := j.jwt.Generate(account, jwtToken.WithExpiry(options.Expiry+time.Hour)) 147 if err != nil { 148 return nil, err 149 } 150 151 return &auth.Token{ 152 Created: access.Created, 153 Expiry: access.Expiry, 154 AccessToken: access.Token, 155 RefreshToken: refresh.Token, 156 }, nil 157 }