github.com/tickoalcantara12/micro/v3@v3.0.0-20221007104245-9d75b9bcbab9/service/auth/jwt/jwt.go (about) 1 // Copyright 2020 Asim Aslam 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 // Original source: github.com/micro/go-micro/v3/auth/jwt/jwt.go 16 17 // Package jwt is a jwt implementation of the auth interface 18 package jwt 19 20 import ( 21 "sync" 22 "time" 23 24 "github.com/tickoalcantara12/micro/v3/service/auth" 25 "github.com/tickoalcantara12/micro/v3/util/auth/rules" 26 "github.com/tickoalcantara12/micro/v3/util/auth/token" 27 "github.com/tickoalcantara12/micro/v3/util/auth/token/jwt" 28 ) 29 30 // NewAuth returns a new instance of the Auth service 31 func NewAuth(opts ...auth.Option) auth.Auth { 32 j := new(jwtAuth) 33 j.Init(opts...) 34 return j 35 } 36 37 type jwtAuth struct { 38 options auth.Options 39 token token.Provider 40 rules []*auth.Rule 41 42 sync.Mutex 43 } 44 45 func (j *jwtAuth) String() string { 46 return "jwt" 47 } 48 49 func (j *jwtAuth) Init(opts ...auth.Option) { 50 j.Lock() 51 defer j.Unlock() 52 53 for _, o := range opts { 54 o(&j.options) 55 } 56 57 j.token = jwt.NewTokenProvider( 58 token.WithPrivateKey(j.options.PrivateKey), 59 token.WithPublicKey(j.options.PublicKey), 60 ) 61 } 62 63 func (j *jwtAuth) Options() auth.Options { 64 j.Lock() 65 defer j.Unlock() 66 return j.options 67 } 68 69 func (j *jwtAuth) Generate(id string, opts ...auth.GenerateOption) (*auth.Account, error) { 70 options := auth.NewGenerateOptions(opts...) 71 if len(options.Issuer) == 0 { 72 options.Issuer = j.Options().Issuer 73 } 74 name := options.Name 75 if name == "" { 76 name = id 77 } 78 account := &auth.Account{ 79 ID: id, 80 Type: options.Type, 81 Scopes: options.Scopes, 82 Metadata: options.Metadata, 83 Issuer: options.Issuer, 84 Name: name, 85 } 86 87 // generate a JWT secret which can be provided to the Token() method 88 // and exchanged for an access token 89 secret, err := j.token.Generate(account, token.WithExpiry(time.Hour*24*365)) 90 if err != nil { 91 return nil, err 92 } 93 account.Secret = secret.Token 94 95 // return the account 96 return account, nil 97 } 98 99 func (j *jwtAuth) Grant(rule *auth.Rule) error { 100 j.Lock() 101 defer j.Unlock() 102 j.rules = append(j.rules, rule) 103 return nil 104 } 105 106 func (j *jwtAuth) Revoke(rule *auth.Rule) error { 107 j.Lock() 108 defer j.Unlock() 109 110 rules := []*auth.Rule{} 111 for _, r := range j.rules { 112 if r.ID != rule.ID { 113 rules = append(rules, r) 114 } 115 } 116 117 j.rules = rules 118 return nil 119 } 120 121 func (j *jwtAuth) Verify(acc *auth.Account, res *auth.Resource, opts ...auth.VerifyOption) error { 122 j.Lock() 123 defer j.Unlock() 124 125 return rules.VerifyAccess(j.rules, acc, res, opts...) 126 } 127 128 func (j *jwtAuth) Rules(opts ...auth.RulesOption) ([]*auth.Rule, error) { 129 j.Lock() 130 defer j.Unlock() 131 return j.rules, nil 132 } 133 134 func (j *jwtAuth) Inspect(token string) (*auth.Account, error) { 135 return j.token.Inspect(token) 136 } 137 138 func (j *jwtAuth) Token(opts ...auth.TokenOption) (*auth.AccountToken, error) { 139 options := auth.NewTokenOptions(opts...) 140 141 secret := options.RefreshToken 142 if len(options.Secret) > 0 { 143 secret = options.Secret 144 } 145 146 account, err := j.token.Inspect(secret) 147 if err != nil { 148 return nil, err 149 } 150 151 access, err := j.token.Generate(account, token.WithExpiry(options.Expiry)) 152 if err != nil { 153 return nil, err 154 } 155 156 refresh, err := j.token.Generate(account, token.WithExpiry(options.Expiry+time.Hour)) 157 if err != nil { 158 return nil, err 159 } 160 161 return &auth.AccountToken{ 162 Created: access.Created, 163 Expiry: access.Expiry, 164 AccessToken: access.Token, 165 RefreshToken: refresh.Token, 166 }, nil 167 }