Google OIDC集成:如何获取外部SSO用户的member_key?
解决Google Workspace外部SAML用户的Cloud Identity API群组验证问题
内部用户的member_key_id直接对应邮箱,但SAML同步的外部用户在Google Workspace中会被分配特殊格式的内部标识符(如name_CompanyA.com@CompanyB.com),该值不会出现在OIDC的id_token或userinfo响应里。解决核心是先通过用户邮箱查询到正确的member_key_id,再执行群组验证。
具体步骤
- 提取用户邮箱:从登录后id_token的
email声明中获取用户的外部邮箱(如name@CompanyA.com)。 - 查询用户真实标识符:调用Cloud Identity API的
users.lookup接口,通过邮箱获取用户完整信息,从中提取正确的member_key_id。 - 验证群组归属:使用拿到的
member_key_id调用groups.memberships.searchDirectGroups接口,执行群组验证逻辑。
Go语言示例代码
package main import ( "context" "fmt" "log" "google.golang.org/api/cloudidentity/v1" "google.golang.org/api/option" "golang.org/x/oauth2" ) // 获取外部用户的member_key_id func getExternalUserMemberKey(ctx context.Context, accessToken, userEmail string) (string, error) { client, err := cloudidentity.NewService(ctx, option.WithTokenSource( &staticTokenSource{token: accessToken}, )) if err != nil { return "", fmt.Errorf("创建Cloud Identity客户端失败: %w", err) } req := &cloudidentity.LookupUserRequest{Email: userEmail} user, err := client.Users.Lookup(req).Do() if err != nil { return "", fmt.Errorf("查询用户信息失败: %w", err) } return user.MemberKey.Id, nil } // 验证用户是否属于目标群组 func checkUserGroupMembership(ctx context.Context, accessToken, memberKeyID, targetGroupID string) (bool, error) { client, err := cloudidentity.NewService(ctx, option.WithTokenSource(&staticTokenSource{token: accessToken})) if err != nil { return false, fmt.Errorf("创建Cloud Identity客户端失败: %w", err) } query := fmt.Sprintf("member_key_id == '%s'", memberKeyID) req := &cloudidentity.SearchDirectGroupsRequest{Query: query} resp, err := client.Groups.Memberships.SearchDirectGroups(targetGroupID, req).Do() if err != nil { return false, fmt.Errorf("查询群组关系失败: %w", err) } return len(resp.Memberships) > 0, nil } // 自定义TokenSource,用于传递用户的access_token type staticTokenSource struct { token string } func (ts *staticTokenSource) Token() (*oauth2.Token, error) { return &oauth2.Token{AccessToken: ts.token}, nil }
关键注意事项
- 权限范围:确保用户的access_token包含
https://www.googleapis.com/auth/cloud-identity或https://www.googleapis.com/auth/cloud-identity.groups.readonly权限,且Workspace管理员已启用Cloud Identity API并授权。 - 异常处理:需处理用户不存在、权限不足等场景(比如SAML同步用户被移除后,查询会返回错误)。
- 服务账号替代方案:后端验证场景可使用服务账号令牌(需配置域范围授权),避免依赖用户令牌的有效期限制。
内容的提问来源于stack exchange,提问作者jkroepke
相关产品推荐
相关产品推荐

