-
Notifications
You must be signed in to change notification settings - Fork 1
/
token_provider.go
76 lines (62 loc) · 1.46 KB
/
token_provider.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
package casdoor
import (
"app/authn"
"context"
"crypto/rsa"
"fmt"
"github.com/golang-jwt/jwt/v5"
"golang.org/x/oauth2"
)
var _ authn.TokenProvider = &TokenProvider{}
type TokenProvider struct {
config Config
publicKey *rsa.PublicKey
oauth oauth2.Config
}
func NewTokenProvider(
config Config,
oauth oauth2.Config,
publicKey *rsa.PublicKey,
) *TokenProvider {
return &TokenProvider{
config: config,
oauth: oauth,
publicKey: publicKey,
}
}
func (provider *TokenProvider) Get(
ctx context.Context,
email string,
password string,
) (*oauth2.Token, error) {
return provider.oauth.PasswordCredentialsToken(ctx, email, password)
}
func (provider *TokenProvider) Parse(rawToken string) (authn.Claims, error) {
claims := authn.Claims{}
parsedToken, parseErr := jwt.Parse(
rawToken,
func(_ *jwt.Token) (any, error) { return provider.publicKey, nil },
jwt.WithValidMethods([]string{"RS256"}),
)
if parseErr != nil {
return claims, parseErr
}
if !parsedToken.Valid {
return claims, jwt.ErrSignatureInvalid
}
tokenClaims, ok := parsedToken.Claims.(jwt.MapClaims)
if !ok {
return claims, fmt.Errorf("failed to parse token claims")
}
if sub, ok := tokenClaims["sub"].(string); !ok {
return claims, fmt.Errorf("missing subject claim")
} else {
claims.Subject = sub
}
if email, ok := tokenClaims["email"].(string); !ok {
return claims, fmt.Errorf("missing email claim")
} else {
claims.Email = email
}
return claims, nil
}