internal TokenRequestPostData GetPostData(string keyValue) { var data = new TokenRequestPostData(); data.keyName = KeyName; data.capability = (Capability ?? Defaults.Capability).ToJson(); data.clientId = ClientId ?? ""; DateTimeOffset now = Config.Now(); if (Nonce.IsNotEmpty()) { data.nonce = Nonce; } if (Ttl.HasValue) { data.ttl = Ttl.Value.TotalMilliseconds.ToString(CultureInfo.InvariantCulture); } else { data.ttl = Defaults.Ttl.TotalMilliseconds.ToString(CultureInfo.InvariantCulture); } if (Timestamp.HasValue) { data.timestamp = Timestamp.Value.ToUnixTimeInMilliseconds().ToString(); } else { data.timestamp = now.ToUnixTimeInMilliseconds().ToString(); } data.CalculateMac(keyValue); return(data); }
/// <summary> /// Makes a token request. This will make a token request now, even if the library already /// has a valid token. It would typically be used to issue tokens for use by other clients. /// </summary> /// <param name="requestData">The <see cref="TokenRequest"/> data used for the token</param> /// <param name="options">Extra <see cref="AuthOptions"/> used for creating a token </param> /// <returns>A valid ably token</returns> /// <exception cref="AblyException"></exception> public TokenDetails RequestToken(TokenRequest requestData, AuthOptions options) { var mergedOptions = options != null?options.Merge(_options) : _options; string keyId = "", keyValue = ""; if (!string.IsNullOrEmpty(mergedOptions.Key)) { var key = mergedOptions.ParseKey(); keyId = key.KeyName; keyValue = key.KeySecret; } var data = requestData ?? new TokenRequest { KeyName = keyId, ClientId = _options.ClientId }; if (requestData == null && options == null && _lastTokenRequest != null) { data = _lastTokenRequest; } data.KeyName = data.KeyName ?? keyId; _lastTokenRequest = data; var request = _rest.CreatePostRequest(String.Format("/keys/{0}/requestToken", data.KeyName)); request.SkipAuthentication = true; TokenRequestPostData postData = null; if (mergedOptions.AuthCallback != null) { var token = mergedOptions.AuthCallback(data); if (token != null) { return(token); } throw new AblyException("AuthCallback returned an invalid token"); } if (mergedOptions.AuthUrl.IsNotEmpty()) { var url = mergedOptions.AuthUrl; var protocol = _options.UseBinaryProtocol == false ? Protocol.Json : Protocol.MsgPack; var authRequest = new AblyRequest(url, mergedOptions.AuthMethod, protocol); if (mergedOptions.AuthMethod == HttpMethod.Get) { authRequest.AddQueryParameters(mergedOptions.AuthParams); } else { authRequest.PostParameters = mergedOptions.AuthParams; } authRequest.Headers.Merge(mergedOptions.AuthHeaders); authRequest.SkipAuthentication = true; var response = _rest.ExecuteRequest(authRequest); if (response.Type != ResponseType.Json) { throw new AblyException( new ErrorInfo( string.Format("Content Type {0} is not supported by this client library", response.ContentType), 500)); } var signedData = response.TextResponse; var jData = JObject.Parse(signedData); if (TokenDetails.IsToken(jData)) { return(jData.ToObject <TokenDetails>()); } postData = JsonConvert.DeserializeObject <TokenRequestPostData>(signedData); } else { postData = data.GetPostData(keyValue); } if (mergedOptions.QueryTime) { postData.timestamp = _rest.Time().ToUnixTimeInMilliseconds().ToString(); } request.PostData = postData; var result = _rest.ExecuteRequest <TokenDetails>(request); if (result == null) { throw new AblyException(new ErrorInfo("Invalid token response returned", 500)); } return(result); }