/// <summary>
        /// Refreshes a short-lived access token using a longer-lived refresh token
        /// with a new access token that has the same scope as the refresh token.
        /// The refresh token itself may also be refreshed.
        /// </summary>
        /// <param name="authorization">The authorization to update.</param>
        /// <param name="skipIfUsefulLifeExceeds">If given, the access token will <em>not</em> be refreshed if its remaining lifetime exceeds this value.</param>
        /// <returns>A value indicating whether the access token was actually renewed; <c>true</c> if it was renewed, or <c>false</c> if it still had useful life remaining.</returns>
        /// <remarks>
        /// This method may modify the value of the <see cref="IAuthorizationState.RefreshToken"/> property on
        /// the <paramref name="authorization"/> parameter if the authorization server has cycled out your refresh token.
        /// If the parameter value was updated, this method calls <see cref="IAuthorizationState.SaveChanges"/> on that instance.
        /// </remarks>
        public bool RefreshAuthorization(IAuthorizationState authorization, TimeSpan?skipIfUsefulLifeExceeds = null)
        {
            Requires.NotNull(authorization, "authorization");
            Requires.That(!string.IsNullOrEmpty(authorization.RefreshToken), "authorization", "RefreshToken required.");

            if (skipIfUsefulLifeExceeds.HasValue && authorization.AccessTokenExpirationUtc.HasValue)
            {
                TimeSpan usefulLifeRemaining = authorization.AccessTokenExpirationUtc.Value - DateTime.UtcNow;
                if (usefulLifeRemaining > skipIfUsefulLifeExceeds.Value)
                {
                    // There is useful life remaining in the access token.  Don't refresh.
                    Logger.OAuth.DebugFormat("Skipping token refresh step because access token's remaining life is {0}, which exceeds {1}.", usefulLifeRemaining, skipIfUsefulLifeExceeds.Value);
                    return(false);
                }
            }

            var request = new AccessTokenRefreshRequestC(this.AuthorizationServer)
            {
                ClientIdentifier = this.ClientIdentifier,
                RefreshToken     = authorization.RefreshToken,
            };

            this.ApplyClientCredential(request);

            var response = this.Channel.Request <AccessTokenSuccessResponse>(request);

            UpdateAuthorizationWithResponse(authorization, response);
            return(true);
        }
Exemple #2
0
        public IAuthorizationState GetScopedAccessTokenAsync(string refreshToken, HashSet <string> scope, CancellationToken cancellationToken)
        {
            var request = new AccessTokenRefreshRequestC(this.AuthorizationServer)
            {
                ClientIdentifier = this.ClientIdentifier,
                RefreshToken     = refreshToken
            };

            this.ApplyClientCredential(request);
            var response      = this.Channel.RequestAsync <AccessTokenSuccessResponse>(request, cancellationToken);
            var authorization = new AuthorizationState();

            UpdateAuthorizationWithResponse(authorization, response);

            return(authorization);
        }
Exemple #3
0
        /// <summary>
        /// Gets an access token that may be used for only a subset of the scope for which a given
        /// refresh token is authorized.
        /// </summary>
        /// <param name="refreshToken">The refresh token.</param>
        /// <param name="scope">The scope subset desired in the access token.</param>
        /// <returns>A description of the obtained access token, and possibly a new refresh token.</returns>
        /// <remarks>
        /// If the return value includes a new refresh token, the old refresh token should be discarded and
        /// replaced with the new one.
        /// </remarks>
        public IAuthorizationState GetScopedAccessToken(string refreshToken, HashSet <string> scope)
        {
            Contract.Ensures(Contract.Result <IAuthorizationState>() != null);

            var request = new AccessTokenRefreshRequestC(this.AuthorizationServer)
            {
                ClientIdentifier = this.ClientIdentifier,
                RefreshToken     = refreshToken,
            };

            this.ApplyClientCredential(request);

            var response      = this.Channel.Request <AccessTokenSuccessResponse>(request);
            var authorization = new AuthorizationState();

            UpdateAuthorizationWithResponse(authorization, response);

            return(authorization);
        }
        /// <summary>
        /// Gets an access token that may be used for only a subset of the scope for which a given
        /// refresh token is authorized.
        /// </summary>
        /// <param name="refreshToken">The refresh token.</param>
        /// <param name="scope">The scope subset desired in the access token.</param>
        /// <returns>A description of the obtained access token, and possibly a new refresh token.</returns>
        /// <remarks>
        /// If the return value includes a new refresh token, the old refresh token should be discarded and
        /// replaced with the new one.
        /// </remarks>
        public IAuthorizationState GetScopedAccessToken(string refreshToken, HashSet <string> scope)
        {
            Requires.NotNullOrEmpty(refreshToken, "refreshToken");
            Requires.NotNull(scope, "scope");

            var request = new AccessTokenRefreshRequestC(this.AuthorizationServer)
            {
                ClientIdentifier = this.ClientIdentifier,
                RefreshToken     = refreshToken,
            };

            this.ApplyClientCredential(request);

            var response      = this.Channel.Request <AccessTokenSuccessResponse>(request);
            var authorization = new AuthorizationState();

            UpdateAuthorizationWithResponse(authorization, response);

            return(authorization);
        }
Exemple #5
0
        public bool RefreshAuthorizationAsync(IAuthorizationState authorization, TimeSpan?skipIfUsefulLifeExceeds = null, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (skipIfUsefulLifeExceeds.HasValue && authorization.AccessTokenExpirationUtc.HasValue)
            {
                TimeSpan usefulLifeRemaining = authorization.AccessTokenExpirationUtc.Value - DateTime.UtcNow;
                if (usefulLifeRemaining > skipIfUsefulLifeExceeds.Value)
                {
                    Logger.OAuth.DebugFormat("Skipping token refresh step because access token's remaining life is {0}, which exceeds {1}.", usefulLifeRemaining, skipIfUsefulLifeExceeds.Value);
                    return(false);
                }
            }
            var request = new AccessTokenRefreshRequestC(this.AuthorizationServer)
            {
                ClientIdentifier = this.ClientIdentifier,
                RefreshToken     = authorization.RefreshToken
            };

            this.ApplyClientCredential(request);
            var response = this.Channel.RequestAsync <AccessTokenSuccessResponse>(request, cancellationToken);

            UpdateAuthorizationWithResponse(authorization, response);

            return(true);
        }
Exemple #6
0
        /// <summary>
        /// Refreshes a short-lived access token using a longer-lived refresh token
        /// with a new access token that has the same scope as the refresh token.
        /// The refresh token itself may also be refreshed.
        /// </summary>
        /// <param name="authorization">The authorization to update.</param>
        /// <param name="skipIfUsefulLifeExceeds">If given, the access token will <em>not</em> be refreshed if its remaining lifetime exceeds this value.</param>
        /// <returns>A value indicating whether the access token was actually renewed; <c>true</c> if it was renewed, or <c>false</c> if it still had useful life remaining.</returns>
        /// <remarks>
        /// This method may modify the value of the <see cref="IAuthorizationState.RefreshToken"/> property on
        /// the <paramref name="authorization"/> parameter if the authorization server has cycled out your refresh token.
        /// If the parameter value was updated, this method calls <see cref="IAuthorizationState.SaveChanges"/> on that instance.
        /// </remarks>
        public bool RefreshAuthorization(IAuthorizationState authorization, TimeSpan?skipIfUsefulLifeExceeds = null)
        {
            if (skipIfUsefulLifeExceeds.HasValue && authorization.AccessTokenExpirationUtc.HasValue)
            {
                TimeSpan usefulLifeRemaining = authorization.AccessTokenExpirationUtc.Value - DateTime.UtcNow;
                if (usefulLifeRemaining > skipIfUsefulLifeExceeds.Value)
                {
                    return(false);
                }
            }

            var request = new AccessTokenRefreshRequestC(this.AuthorizationServer)
            {
                ClientIdentifier = this.ClientIdentifier,
                RefreshToken     = authorization.RefreshToken,
            };

            this.ApplyClientCredential(request);

            var response = this.Channel.Request <AccessTokenSuccessResponse>(request);

            UpdateAuthorizationWithResponse(authorization, response);
            return(true);
        }