Наследование: ExtensibleJsonObject
        /// <summary>
        /// Initializes a new instance of the <see cref="IdentityV2AuthenticationService"/> class with the specified
        /// OpenStack Identity Service V2 client and prepared authentication request.
        /// </summary>
        /// <param name="identityService">The <see cref="IIdentityService"/> instance to use for authentication
        /// purposes.</param>
        /// <param name="authenticationRequest">The authentication request, which contains the credentials to use for
        /// authenticating with the OpenStack Identity Service V2.</param>
        /// <exception cref="ArgumentNullException">
        /// <para>If <paramref name="identityService"/> is <see langword="null"/>.</para>
        /// <para>-or-</para>
        /// <para>If <paramref name="authenticationRequest"/> is <see langword="null"/>.</para>
        /// </exception>
        public IdentityV2AuthenticationService(IIdentityService identityService, AuthenticationRequest authenticationRequest)
        {
            if (identityService == null)
                throw new ArgumentNullException("identityService");
            if (authenticationRequest == null)
                throw new ArgumentNullException("authenticationRequest");

            _identityService = identityService;
            _authenticationRequest = authenticationRequest;
        }
        /// <summary>
        /// Create an <see cref="AuthenticationRequest"/> using the specified username and API key as credentials.
        /// </summary>
        /// <param name="username">The account username.</param>
        /// <param name="apiKey">The account API key.</param>
        /// <returns>
        /// <para>An <see cref="AuthenticationRequest"/> instance containing the specified credentials, which is
        /// typically used for constructing an instance of <see cref="RackspaceAuthenticationService"/>.</para>
        /// </returns>
        /// <exception cref="ArgumentNullException">
        /// <para>If <paramref name="username"/> is <see langword="null"/>.</para>
        /// <para>-or-</para>
        /// <para>If <paramref name="apiKey"/> is <see langword="null"/>.</para>
        /// </exception>
        /// <exception cref="ArgumentException">
        /// <para>If <paramref name="username"/> is empty.</para>
        /// <para>-or-</para>
        /// <para>If <paramref name="apiKey"/> is empty.</para>
        /// </exception>
        public static AuthenticationRequest ApiKey(string username, string apiKey)
        {
            if (username == null)
                throw new ArgumentNullException("username");
            if (apiKey == null)
                throw new ArgumentNullException("apiKey");
            if (string.IsNullOrEmpty(username))
                throw new ArgumentException("username cannot be empty");
            if (string.IsNullOrEmpty(apiKey))
                throw new ArgumentException("apiKey cannot be empty");

            var extensionData = ImmutableDictionary<string, JToken>.Empty
                .Add("RAX-KSKEY:apiKeyCredentials", new JObject(
                    new JProperty("username", username),
                    new JProperty("apiKey", apiKey)));
            AuthenticationData authenticationData = new AuthenticationData(extensionData);

            AuthenticationRequest authenticationRequest = new AuthenticationRequest(authenticationData);
            return authenticationRequest;
        }
        /// <summary>
        /// Create an <see cref="AuthenticationRequest"/> using the specified username and password as credentials.
        /// </summary>
        /// <remarks>
        /// <note type="warning">
        /// For improved security, clients are encouraged to use API key credentials instead of a password whenever
        /// possible.
        /// </note>
        /// </remarks>
        /// <param name="username">The account username.</param>
        /// <param name="password">The account password.</param>
        /// <returns>
        /// <para>An <see cref="AuthenticationRequest"/> instance containing the specified credentials, which is
        /// typically used for constructing an instance of <see cref="RackspaceAuthenticationService"/>.</para>
        /// </returns>
        /// <exception cref="ArgumentNullException">
        /// <para>If <paramref name="username"/> is <see langword="null"/>.</para>
        /// <para>-or-</para>
        /// <para>If <paramref name="password"/> is <see langword="null"/>.</para>
        /// </exception>
        /// <exception cref="ArgumentException">
        /// <para>If <paramref name="username"/> is empty.</para>
        /// <para>-or-</para>
        /// <para>If <paramref name="password"/> is empty.</para>
        /// </exception>
        public static AuthenticationRequest Password(string username, string password)
        {
            if (username == null)
                throw new ArgumentNullException("username");
            if (password == null)
                throw new ArgumentNullException("password");
            if (string.IsNullOrEmpty(username))
                throw new ArgumentException("username cannot be empty");
            if (string.IsNullOrEmpty(password))
                throw new ArgumentException("password cannot be empty");

            PasswordCredentials passwordCredentials = new PasswordCredentials(username, password);
            AuthenticationData authenticationData = new AuthenticationData(passwordCredentials);
            AuthenticationRequest authenticationRequest = new AuthenticationRequest(authenticationData);
            return authenticationRequest;
        }
        /// <summary>
        /// Prepare and send an HTTP API call to obtain a authenticate a set of credentials with the OpenStack Identity
        /// Service V2.
        /// </summary>
        /// <param name="service">The <see cref="IIdentityService"/> instance.</param>
        /// <param name="request">An <seealso cref="AuthenticationRequest"/> object containing the credentials to
        /// authenticate.</param>
        /// <param name="cancellationToken">The <seealso cref="CancellationToken"/> that the task will observe.</param>
        /// <returns>
        /// A <seealso cref="Task"/> representing the asynchronous operation. When the task completes successfully, the
        /// <see cref="Task{TResult}.Result"/> property will contain an <see cref="Access"/> instance containing the
        /// authentication details.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        /// <para>If <paramref name="service"/> is <see langword="null"/>.</para>
        /// </exception>
        /// <exception cref="HttpWebException">
        /// If an error occurs during an HTTP request as part of preparing or sending the API call.
        /// </exception>
        /// <seealso cref="IIdentityService.PrepareAuthenticateAsync"/>
        /// <seealso href="http://developer.openstack.org/api-ref-identity-v2.html#identity-auth-v2">Tokens (Identity API v2.0 - OpenStack Complete API Reference)</seealso>
        public static Task<Access> AuthenticateAsync(this IIdentityService service, AuthenticationRequest request, CancellationToken cancellationToken)
        {
            if (service == null)
                throw new ArgumentNullException("service");

            return TaskBlocks.Using(
                () => service.PrepareAuthenticateAsync(request, cancellationToken),
                task => task.Result.SendAsync(cancellationToken).Select(innerTask => innerTask.Result.Item2.Access));
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="RackspaceAuthenticationService"/> class with the specified
 /// identity service and prepared authentication request.
 /// </summary>
 /// <param name="identityService">
 /// The <see cref="IIdentityService"/> instance to use for authentication purposes.
 /// </param>
 /// <param name="authenticationRequest">The authentication request, which contains the credentials to use for
 /// authenticating with Rackspace Cloud Identity.</param>
 /// <exception cref="ArgumentNullException">
 /// <para>If <paramref name="identityService"/> is <see langword="null"/>.</para>
 /// <para>-or-</para>
 /// <para>If <paramref name="authenticationRequest"/> is <see langword="null"/>.</para>
 /// </exception>
 public RackspaceAuthenticationService(IIdentityService identityService, AuthenticationRequest authenticationRequest)
     : base(identityService, authenticationRequest)
 {
 }