...
1
21
22 package oauth2
23
24 import (
25 "context"
26 "time"
27
28 "github.com/ory/fosite"
29 "github.com/ory/fosite/token/jwt"
30 )
31
32 type StatelessJWTValidator struct {
33 jwt.JWTStrategy
34 ScopeStrategy fosite.ScopeStrategy
35 }
36
37
38 func AccessTokenJWTToRequest(token *jwt.Token) fosite.Requester {
39 mapClaims := token.Claims
40 claims := jwt.JWTClaims{}
41 claims.FromMapClaims(mapClaims)
42
43 requestedAt := claims.IssuedAt
44 requestedAtClaim, ok := mapClaims["rat"]
45 if ok {
46 switch requestedAtClaim.(type) {
47 case float64:
48 requestedAt = time.Unix(int64(requestedAtClaim.(float64)), 0).UTC()
49 case int64:
50 requestedAt = time.Unix(requestedAtClaim.(int64), 0).UTC()
51 }
52 }
53
54 clientId := ""
55 clientIdClaim, ok := mapClaims["client_id"]
56 if ok {
57 switch clientIdClaim.(type) {
58 case string:
59 clientId = clientIdClaim.(string)
60 }
61 }
62
63 return &fosite.Request{
64 RequestedAt: requestedAt,
65 Client: &fosite.DefaultClient{
66 ID: clientId,
67 },
68
69 RequestedScope: claims.Scope,
70 GrantedScope: claims.Scope,
71 Session: &JWTSession{
72 JWTClaims: &claims,
73 JWTHeader: &jwt.Headers{
74 Extra: token.Header,
75 },
76 ExpiresAt: map[fosite.TokenType]time.Time{
77 fosite.AccessToken: claims.ExpiresAt,
78 },
79 Subject: claims.Subject,
80 },
81
82 RequestedAudience: claims.Audience,
83 GrantedAudience: claims.Audience,
84 }
85 }
86
87 func (v *StatelessJWTValidator) IntrospectToken(ctx context.Context, token string, tokenUse fosite.TokenUse, accessRequest fosite.AccessRequester, scopes []string) (fosite.TokenUse, error) {
88 t, err := validate(ctx, v.JWTStrategy, token)
89 if err != nil {
90 return "", err
91 }
92
93
94
95 requester := AccessTokenJWTToRequest(t)
96
97 if err := matchScopes(v.ScopeStrategy, requester.GetGrantedScopes(), scopes); err != nil {
98 return fosite.AccessToken, err
99 }
100
101 accessRequest.Merge(requester)
102
103 return fosite.AccessToken, nil
104 }
105
View as plain text