Skip to content

Commit 57e500d

Browse files
committed
refactor(tokenparser): simplify default parser
Simplify the default identity provider response parser by extracting the raw token from the response and then parsing it as jwt token.
1 parent 3b9fcb7 commit 57e500d

File tree

3 files changed

+46
-81
lines changed

3 files changed

+46
-81
lines changed

internal/idp_response.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,17 +36,17 @@ func NewIDPResp(resultType string, result interface{}) (*IDPResp, error) {
3636
default:
3737
return nil, fmt.Errorf("invalid auth result type: expected public.AuthResult or *public.AuthResult, got %T", result)
3838
}
39+
r.rawTokenVal = r.authResultVal.AccessToken
3940
case "AccessToken":
4041
switch v := result.(type) {
4142
case *azcore.AccessToken:
4243
r.accessTokenVal = v
43-
r.rawTokenVal = v.Token
4444
case azcore.AccessToken:
4545
r.accessTokenVal = &v
46-
r.rawTokenVal = v.Token
4746
default:
4847
return nil, fmt.Errorf("invalid access token type: expected azcore.AccessToken or *azcore.AccessToken, got %T", result)
4948
}
49+
r.rawTokenVal = r.accessTokenVal.Token
5050
case "RawToken":
5151
switch v := result.(type) {
5252
case string:

manager/defaults.go

Lines changed: 38 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,8 @@ type defaultIdentityProviderResponseParser struct{}
9696

9797
// ParseResponse parses the response from the identity provider and extracts the token.
9898
// It takes an IdentityProviderResponse as an argument and returns a Token and an error if any.
99-
// The IdentityProviderResponse contains the raw token and the expiration time.
99+
// The raw token is extracted based on the IdentityProviderResponse Type and then
100+
// is parsed as a JWT token to extract the claims.
100101
func (*defaultIdentityProviderResponseParser) ParseResponse(response shared.IdentityProviderResponse) (*token.Token, error) {
101102
if response == nil {
102103
return nil, fmt.Errorf("identity provider response cannot be nil")
@@ -113,82 +114,51 @@ func (*defaultIdentityProviderResponseParser) ParseResponse(response shared.Iden
113114
return nil, fmt.Errorf("failed to get auth result: %w", err)
114115
}
115116

116-
claims := struct {
117-
jwt.RegisteredClaims
118-
Oid string `json:"oid,omitempty"`
119-
}{}
120-
121-
// Parse the token to extract claims, but note that signature verification
122-
// should be handled by the identity provider
123-
_, _, err = jwt.NewParser().ParseUnverified(authResult.AccessToken, &claims)
124-
if err != nil {
125-
return nil, fmt.Errorf("failed to parse JWT token: %w", err)
126-
}
127-
128-
if claims.Oid == "" {
129-
return nil, fmt.Errorf("auth result OID is empty")
130-
}
131-
132-
if claims.ExpiresAt.IsZero() {
133-
return nil, fmt.Errorf("auth result expiration time is not set")
134-
}
135-
117+
expiresOn = authResult.ExpiresOn.UTC()
136118
rawToken = authResult.AccessToken
137-
username = claims.Oid
138-
password = rawToken
139-
expiresOn = claims.ExpiresAt.UTC()
140-
141-
case shared.ResponseTypeRawToken, shared.ResponseTypeAccessToken:
142-
var tokenStr string
143-
var err error
144-
if response.Type() == shared.ResponseTypeRawToken {
145-
tokenStr, err = response.(shared.RawTokenIDPResponse).RawToken()
146-
if err != nil {
147-
return nil, fmt.Errorf("failed to get raw token: %w", err)
148-
}
149-
}
150-
if response.Type() == shared.ResponseTypeAccessToken {
151-
accessToken, err := response.(shared.AccessTokenIDPResponse).AccessToken()
152-
if err != nil {
153-
return nil, fmt.Errorf("failed to get access token: %w", err)
154-
}
155-
if accessToken.Token == "" {
156-
return nil, fmt.Errorf("access token value is empty")
157-
}
158-
tokenStr = accessToken.Token
159-
expiresOn = accessToken.ExpiresOn.UTC()
160-
}
161-
162-
if tokenStr == "" {
163-
return nil, fmt.Errorf("raw token is empty")
119+
case shared.ResponseTypeAccessToken:
120+
accessToken, err := response.(shared.AccessTokenIDPResponse).AccessToken()
121+
if err != nil {
122+
return nil, fmt.Errorf("failed to get access token: %w", err)
164123
}
165124

166-
claims := struct {
167-
jwt.RegisteredClaims
168-
Oid string `json:"oid,omitempty"`
169-
}{}
170-
171-
// Parse the token to extract claims, but note that signature verification
172-
// should be handled by the identity provider
173-
_, _, err = jwt.NewParser().ParseUnverified(tokenStr, &claims)
125+
rawToken = accessToken.Token
126+
expiresOn = accessToken.ExpiresOn.UTC()
127+
case shared.ResponseTypeRawToken:
128+
tokenStr, err := response.(shared.RawTokenIDPResponse).RawToken()
174129
if err != nil {
175-
return nil, fmt.Errorf("failed to parse JWT token: %w", err)
130+
return nil, fmt.Errorf("failed to get raw token: %w", err)
176131
}
132+
rawToken = tokenStr
133+
default:
134+
return nil, fmt.Errorf("unsupported response type: %s", response.Type())
135+
}
177136

178-
if claims.Oid == "" {
179-
return nil, fmt.Errorf("JWT token does not contain OID claim")
180-
}
137+
if rawToken == "" {
138+
return nil, fmt.Errorf("raw token is empty")
139+
}
181140

182-
rawToken = tokenStr
183-
username = claims.Oid
184-
password = rawToken
141+
// Parse JWT
142+
claims := struct {
143+
jwt.RegisteredClaims
144+
Oid string `json:"oid,omitempty"`
145+
}{}
146+
147+
// Parse the token to extract claims, but note that signature verification
148+
// should be handled by the identity provider
149+
_, _, err := jwt.NewParser().ParseUnverified(rawToken, &claims)
150+
if err != nil {
151+
return nil, fmt.Errorf("failed to parse JWT token: %w", err)
152+
}
185153

186-
if expiresOn.IsZero() && claims.ExpiresAt != nil {
187-
expiresOn = claims.ExpiresAt.UTC()
188-
}
154+
if claims.Oid == "" {
155+
return nil, fmt.Errorf("JWT token does not contain OID claim")
156+
}
189157

190-
default:
191-
return nil, fmt.Errorf("unsupported response type: %s", response.Type())
158+
username = claims.Oid
159+
password = rawToken
160+
if expiresOn.IsZero() && claims.ExpiresAt != nil {
161+
expiresOn = claims.ExpiresAt.UTC()
192162
}
193163

194164
if expiresOn.IsZero() {

shared/identity_provider_response.go

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,15 @@ type IdentityProviderResponseParser interface {
4343
type IdentityProviderResponse interface {
4444
// Type returns the type of identity provider response
4545
Type() string
46+
// RawToken returns the raw token string.
47+
// Returns ErrRawTokenNotFound if the raw token is not set.
48+
RawToken() (string, error)
4649
}
4750

4851
// AuthResultIDPResponse is an interface that defines the method for getting the auth result.
4952
// Returns ErrAuthResultNotFound if the auth result is not set.
5053
type AuthResultIDPResponse interface {
54+
IdentityProviderResponse
5155
// AuthResult returns the Microsoft Authentication Library AuthResult.
5256
// Returns ErrAuthResultNotFound if the auth result is not set.
5357
AuthResult() (public.AuthResult, error)
@@ -56,28 +60,19 @@ type AuthResultIDPResponse interface {
5660
// AccessTokenIDPResponse is an interface that defines the method for getting the access token.
5761
// Returns ErrAccessTokenNotFound if the access token is not set.
5862
type AccessTokenIDPResponse interface {
63+
IdentityProviderResponse
5964
// AccessToken returns the Azure SDK AccessToken.
6065
// Returns ErrAccessTokenNotFound if the access token is not set.
6166
AccessToken() (azcore.AccessToken, error)
6267
}
6368

64-
// RawTokenIDPResponse is an interface that defines the method for getting the raw token.
65-
// Returns ErrRawTokenNotFound if the raw token is not set.
6669
type RawTokenIDPResponse interface {
67-
// RawToken returns the raw token string.
68-
// Returns ErrRawTokenNotFound if the raw token is not set.
69-
RawToken() (string, error)
70+
IdentityProviderResponse
7071
}
7172

7273
// IdentityProvider is an interface that defines the methods for an identity provider.
7374
// It is used to request a token for authentication.
7475
// The identity provider is responsible for providing the raw authentication token.
75-
// Available errors:
76-
// - ErrInvalidIDPResponse: When the response from the identity provider is invalid
77-
// - ErrInvalidIDPResponseType: When the response type is not supported
78-
// - ErrAuthResultNotFound: When trying to get an AuthResult that is not set
79-
// - ErrAccessTokenNotFound: When trying to get an AccessToken that is not set
80-
// - ErrRawTokenNotFound: When trying to get a RawToken that is not set
8176
type IdentityProvider interface {
8277
// RequestToken requests a token from the identity provider.
8378
// The context is passed to the request to allow for cancellation and timeouts.

0 commit comments

Comments
 (0)