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