github.com/livekit/protocol@v1.16.1-0.20240517185851-47e4c6bba773/auth/verifier.go (about) 1 // Copyright 2023 LiveKit, Inc. 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 // http://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 package auth 16 17 import ( 18 "time" 19 20 "github.com/go-jose/go-jose/v3/jwt" 21 ) 22 23 type APIKeyTokenVerifier struct { 24 token *jwt.JSONWebToken 25 identity string 26 apiKey string 27 } 28 29 // ParseAPIToken parses an encoded JWT token and 30 func ParseAPIToken(raw string) (*APIKeyTokenVerifier, error) { 31 tok, err := jwt.ParseSigned(raw) 32 if err != nil { 33 return nil, err 34 } 35 36 out := jwt.Claims{} 37 if err := tok.UnsafeClaimsWithoutVerification(&out); err != nil { 38 return nil, err 39 } 40 41 v := &APIKeyTokenVerifier{ 42 token: tok, 43 apiKey: out.Issuer, 44 identity: out.Subject, 45 } 46 if v.identity == "" { 47 v.identity = out.ID 48 } 49 return v, nil 50 } 51 52 // APIKey returns the API key this token was signed with 53 func (v *APIKeyTokenVerifier) APIKey() string { 54 return v.apiKey 55 } 56 57 func (v *APIKeyTokenVerifier) Identity() string { 58 return v.identity 59 } 60 61 func (v *APIKeyTokenVerifier) Verify(key interface{}) (*ClaimGrants, error) { 62 if key == nil || key == "" { 63 return nil, ErrKeysMissing 64 } 65 if s, ok := key.(string); ok { 66 key = []byte(s) 67 } 68 out := jwt.Claims{} 69 claims := ClaimGrants{} 70 if err := v.token.Claims(key, &out, &claims); err != nil { 71 return nil, err 72 } 73 if err := out.Validate(jwt.Expected{Issuer: v.apiKey, Time: time.Now()}); err != nil { 74 return nil, err 75 } 76 77 // copy over identity 78 claims.Identity = v.identity 79 return &claims, nil 80 }