MCPcopy
hub / github.com/containerd/containerd / doBearerAuth

Method doBearerAuth

core/remotes/docker/authorizer.go:275–349  ·  view source on GitHub ↗
(ctx context.Context)

Source from the content-addressed store, hash-verified

273}
274
275func (ah *authHandler) doBearerAuth(ctx context.Context) (token, refreshToken string, err error) {
276 // copy common tokenOptions
277 to := ah.common
278
279 to.Scopes = GetTokenScopes(ctx, to.Scopes)
280
281 // Docs: https://distribution.github.io/distribution/spec/auth/scope/
282 scoped := strings.Join(to.Scopes, " ")
283
284 // Keep track of the expiration time of cached bearer tokens so they can be
285 // refreshed when they expire without a server roundtrip.
286 var expirationTime *time.Time
287
288 ah.Lock()
289 if r, exist := ah.scopedTokens[scoped]; exist && (r.expirationTime == nil || r.expirationTime.After(time.Now())) {
290 ah.Unlock()
291 r.Wait()
292 return r.token, r.refreshToken, r.err
293 }
294
295 // only one fetch token job
296 r := new(authResult)
297 r.Add(1)
298 ah.scopedTokens[scoped] = r
299 ah.Unlock()
300
301 defer func() {
302 token = fmt.Sprintf("Bearer %s", token)
303 r.token, r.refreshToken, r.err, r.expirationTime = token, refreshToken, err, expirationTime
304 r.Done()
305 }()
306
307 // fetch token for the resource scope
308 if to.Secret != "" {
309 defer func() {
310 if err != nil {
311 err = fmt.Errorf("failed to fetch oauth token: %w", err)
312 }
313 }()
314 // credential information is provided, use oauth POST endpoint
315 // TODO: Allow setting client_id
316 resp, err := auth.FetchTokenWithOAuth(ctx, ah.client, ah.header, "containerd-client", to)
317 if err != nil {
318 var errStatus remoteerrors.ErrUnexpectedStatus
319 if errors.As(err, &errStatus) {
320 // Registries without support for POST may return 404 for POST /v2/token.
321 // As of September 2017, GCR is known to return 404.
322 // As of February 2018, JFrog Artifactory is known to return 401.
323 // As of January 2022, ACR is known to return 400.
324 if (errStatus.StatusCode == 405 && to.Username != "") || errStatus.StatusCode == 404 || errStatus.StatusCode == 401 || errStatus.StatusCode == 400 {
325 resp, err := auth.FetchToken(ctx, ah.client, ah.header, to)
326 if err != nil {
327 return "", "", err
328 }
329 expirationTime = getExpirationTime(resp.ExpiresInSeconds)
330 return resp.Token, resp.RefreshToken, nil
331 }
332 log.G(ctx).WithFields(log.Fields{

Callers 1

authorizeMethod · 0.95

Calls 10

FetchTokenWithOAuthFunction · 0.92
FetchTokenFunction · 0.92
GetTokenScopesFunction · 0.85
newFunction · 0.85
getExpirationTimeFunction · 0.85
LockMethod · 0.65
UnlockMethod · 0.65
WaitMethod · 0.65
AddMethod · 0.65
DoneMethod · 0.65

Tested by

no test coverage detected