private static async Task <CreateTokenResponse> PollForSsoTokenAsync(IAmazonSSOOIDC client, CreateTokenRequest createTokenRequest, int pollingIntervalSeconds, DateTime deviceCodeExpiration, IGetSsoTokenContext context) { var logger = Logger.GetLogger(typeof(CoreAmazonSSOOIDC)); // Spec: If the Interval value is not returned as part of the StartDeviceAuthorization response, // a default Interval value of 5 seconds should be used. var intervalSec = pollingIntervalSeconds > 0 ? pollingIntervalSeconds : DefaultPollingIntervalSeconds; // Poll for Token until success, failure, or an error condition arises. while (true) { try { var response = await client.CreateTokenAsync(createTokenRequest).ConfigureAwait(false); // If we reach here, the user has completed the SSO Login authorization. return(response); } catch (AuthorizationPendingException e) { // Service is still waiting for user to complete authorization. // Repeat the loop after an interval. } catch (SlowDownException e) { // Spec: Add 5 seconds to the polling interval intervalSec += PollingSlowdownIncrementSeconds; } catch (ExpiredTokenException e) { // Spec: An exception must be raised, indicating that the SSO login window expired // and the SSO login flow must be re-initiated. throw new AmazonSSOOIDCException("Device code has expired while polling for SSO token, login flow must be re-initiated.", e); } catch (TimeoutException e) { // Spec: If the call times out then the tool should double its polling interval and then retry. intervalSec *= 2; } catch (Exception e) { logger.Error(e, "Unexpected exception while polling for SSO Token."); throw; } if (DateTime.UtcNow.AddSeconds(intervalSec) > deviceCodeExpiration) { throw new AmazonSSOOIDCException("Device code has expired while polling for SSO token, login flow must be re-initiated."); } context.Sleep(intervalSec * 1000); } // while(polling) }
public static GetSsoTokenResponse GetSsoToken(IAmazonSSOOIDC client, GetSsoTokenRequest request, IGetSsoTokenContext context) { var registerClientRequest = new RegisterClientRequest() { ClientName = request.ClientName, ClientType = request.ClientType, }; InternalSDKUtils.ApplyValues(registerClientRequest, request.AdditionalProperties); var registerClientResponse = client.RegisterClient(registerClientRequest); var startDeviceAuthorizationRequest = new StartDeviceAuthorizationRequest() { ClientSecret = registerClientResponse.ClientSecret, ClientId = registerClientResponse.ClientId, StartUrl = request.StartUrl, }; InternalSDKUtils.ApplyValues(startDeviceAuthorizationRequest, request.AdditionalProperties); var startDeviceAuthorizationResponse = client.StartDeviceAuthorization(startDeviceAuthorizationRequest); // Spec: The expiration time must be calculated by adding the number of seconds // returned by StartDeviceAuthorization (ExpiresIn) to the current time. DateTime deviceCodeExpiration = DateTime.UtcNow.AddSeconds(startDeviceAuthorizationResponse.ExpiresIn); request.SsoVerificationCallback(new SsoVerificationArguments() { UserCode = startDeviceAuthorizationResponse.UserCode, VerificationUri = startDeviceAuthorizationResponse.VerificationUri, VerificationUriComplete = startDeviceAuthorizationResponse.VerificationUriComplete, }); var createTokenRequest = new CreateTokenRequest() { ClientId = registerClientResponse.ClientId, ClientSecret = registerClientResponse.ClientSecret, GrantType = CreateTokenGrantType, DeviceCode = startDeviceAuthorizationResponse.DeviceCode, }; InternalSDKUtils.ApplyValues(request, request.AdditionalProperties); var ssoToken = PollForSsoToken(client, createTokenRequest, startDeviceAuthorizationResponse.Interval, deviceCodeExpiration, context); return(new GetSsoTokenResponse() { AccessToken = ssoToken.AccessToken, ExpiresAt = DateTime.UtcNow.AddSeconds(ssoToken.ExpiresIn), }); }