wip: account details from az and the token
This commit is contained in:
1 parent
87d98d038d
commit
482e0805b7
6 files changed
+218
-17
No files matched your search
@@ -42,6 +42,16 @@ type cliCredential struct {
|
||||
|
||||
mu sync.Mutex
|
||||
cache map[string]azcore.AccessToken // by resource and tenant argument
|
||||
// last is the claims of the latest token in the account's own
|
||||
// tenant, to describe the account (Provider.Account).
|
||||
last map[string]any
|
||||
}
|
||||
|
||||
// claims are the latest token's claims, nil before the first.
|
||||
func (c *cliCredential) claims() map[string]any {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
return c.last
|
||||
}
|
||||
|
||||
func newCLICredential(user, tenant string, accounts func() ([]account, error)) *cliCredential {
|
||||
@@ -110,29 +120,38 @@ func (c *cliCredential) GetToken(ctx context.Context, opts policy.TokenRequestOp
|
||||
if err != nil {
|
||||
return azcore.AccessToken{}, err
|
||||
}
|
||||
if u, ok := tokenUser(tok.Token, others); ok {
|
||||
claims := tokenClaims(tok.Token)
|
||||
if u, ok := tokenUser(claims, others); ok {
|
||||
return azcore.AccessToken{}, fmt.Errorf("az gave a token for %s, not %s: sign in as %s again", u, c.user, c.user)
|
||||
}
|
||||
if !otherTenant && claims != nil {
|
||||
c.last = claims
|
||||
}
|
||||
c.cache[key] = tok
|
||||
return tok, nil
|
||||
}
|
||||
|
||||
// tokenUser reports which of users a token was issued to, if any, from
|
||||
// its claims. The token isn't verified: this only catches az picking the
|
||||
// wrong signed-in account.
|
||||
func tokenUser(token string, users []string) (string, bool) {
|
||||
// tokenClaims reads a JWT's claims, without verifying it: they only
|
||||
// describe the account and catch az picking the wrong one. nil if it
|
||||
// isn't a JWT.
|
||||
func tokenClaims(token string) map[string]any {
|
||||
parts := strings.Split(token, ".")
|
||||
if len(parts) != 3 || len(users) == 0 {
|
||||
return "", false
|
||||
if len(parts) != 3 {
|
||||
return nil
|
||||
}
|
||||
b, err := base64.RawURLEncoding.DecodeString(strings.TrimRight(parts[1], "="))
|
||||
if err != nil {
|
||||
return "", false
|
||||
return nil
|
||||
}
|
||||
var claims map[string]any
|
||||
if json.Unmarshal(b, &claims) != nil {
|
||||
return "", false
|
||||
return nil
|
||||
}
|
||||
return claims
|
||||
}
|
||||
|
||||
// tokenUser reports which of users a token's claims are for, if any.
|
||||
func tokenUser(claims map[string]any, users []string) (string, bool) {
|
||||
for _, name := range []string{"upn", "unique_name", "preferred_username", "email"} {
|
||||
v, _ := claims[name].(string)
|
||||
if i := strings.LastIndexByte(v, '#'); i >= 0 {
|
||||
|
||||
Reference in new issue
Block a user