internal AblyAuth(ClientOptions options, AblyRest rest) { Now = options.NowFunc; Options = options; _rest = rest; Logger = options.Logger; ServerTime = () => _rest.TimeAsync(); ServerTimeOffset = () => null; Initialise(); }
/// <summary> /// Create a signed token request based on known credentials /// and the given token params. This would typically be used if creating /// signed requests for submission by another client. /// </summary> /// <param name="tokenParams"><see cref="TokenParams"/>. If null a token request is generated from options passed when the client was created.</param> /// <param name="authOptions"><see cref="AuthOptions"/>. If null the default AuthOptions are used.</param> /// <returns></returns> public async Task <string> CreateTokenRequestAsync(TokenParams tokenParams, AuthOptions authOptions) { authOptions = authOptions ?? CurrentAuthOptions ?? Options; tokenParams = tokenParams ?? CurrentTokenParams ?? TokenParams.WithDefaultsApplied(); if (string.IsNullOrEmpty(authOptions.Key)) { throw new AblyException("No key specified", 40101, HttpStatusCode.Unauthorized); } await SetTokenParamsTimestamp(authOptions, tokenParams); if (authOptions.QueryTime.GetValueOrDefault(false)) { tokenParams.Timestamp = await _rest.TimeAsync(); } var apiKey = authOptions.ParseKey(); var request = new TokenRequest(Now).Populate(tokenParams, apiKey.KeyName, apiKey.KeySecret); return(JsonHelper.Serialize(request)); }
/// <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="tokenParams">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 virtual async Task <TokenDetails> RequestTokenAsync(TokenParams tokenParams = null, AuthOptions options = null) { var mergedOptions = options != null?options.Merge(Options) : Options; string keyId = "", keyValue = ""; if (mergedOptions.Key.IsNotEmpty()) { var key = mergedOptions.ParseKey(); keyId = key.KeyName; keyValue = key.KeySecret; } var @params = MergeTokenParamsWithDefaults(tokenParams); if (mergedOptions.QueryTime.GetValueOrDefault(false)) { @params.Timestamp = await _rest.TimeAsync(); } EnsureSecureConnection(); var request = _rest.CreatePostRequest($"/keys/{keyId}/requestToken"); request.SkipAuthentication = true; TokenRequest postData = null; if (mergedOptions.AuthCallback != null) { var callbackResult = await mergedOptions.AuthCallback(@params); if (callbackResult == null) { throw new AblyException("AuthCallback returned null"); } if (callbackResult is TokenDetails) { return(callbackResult as TokenDetails); } if (callbackResult is TokenRequest) { postData = callbackResult as TokenRequest; request.Url = $"/keys/{postData.KeyName}/requestToken"; } else { throw new AblyException($"AuthCallback returned an unsupported type ({callbackResult.GetType()}. Expected either TokenDetails or TokenRequest"); } } else if (mergedOptions.AuthUrl.IsNotEmpty()) { var response = await CallAuthUrl(mergedOptions, @params); if (response.Type == ResponseType.Text) //Return token string { return(new TokenDetails(response.TextResponse)); } var signedData = response.TextResponse; var jData = JObject.Parse(signedData); if (TokenDetails.IsToken(jData)) { return(JsonHelper.DeserializeObject <TokenDetails>(jData)); } postData = JsonHelper.Deserialize <TokenRequest>(signedData); request.Url = $"/keys/{postData.KeyName}/requestToken"; } else { if (keyId.IsEmpty() || keyValue.IsEmpty()) { throw new AblyException("TokenAuth is on but there is no way to generate one"); } postData = new TokenRequest().Populate(@params, keyId, keyValue); } request.PostData = postData; TokenDetails result = await _rest.ExecuteRequest <TokenDetails>(request); if (result == null) { throw new AblyException(new ErrorInfo("Invalid token response returned", 500)); } return(result); }