aliyun-net-credentials/Provider/URLCredentialProvider.cs (182 lines of code) (raw):

using System; using System.Text; using System.Collections.Generic; using System.Threading.Tasks; using Aliyun.Credentials.Exceptions; using Aliyun.Credentials.Http; using Aliyun.Credentials.Models; using Aliyun.Credentials.Utils; using Newtonsoft.Json; using Tea.Utils; namespace Aliyun.Credentials.Provider { /// <summary> /// By specifying the url, the credential will be able to automatically request maintenance of STS Token. /// </summary> public class URLCredentialProvider : SessionCredentialsProvider { private readonly Uri credentialsURI; /// <summary> /// Unit of millsecond. /// </summary> private int connectTimeout = 5000; private int readTimeout = 10000; [Obsolete("Use builder instead.")] public URLCredentialProvider(Config config) : this(config.CredentialsURI) { connectTimeout = config.ConnectTimeout; readTimeout = config.Timeout; } [Obsolete("Use builder instead.")] public URLCredentialProvider(string credentialsURI) { try { string uriStr = credentialsURI ?? Environment.GetEnvironmentVariable("ALIBABA_CLOUD_CREDENTIALS_URI"); this.credentialsURI = new Uri(ParameterHelper.ValidateNotEmpty(uriStr, "credentialsURI", "Credentials URI must not be null or empty.")); } catch (UriFormatException) { throw new CredentialException("Credential URI is not valid."); } } private URLCredentialProvider(Builder builder): base(builder) { this.connectTimeout = (builder.connectTimeout == null || builder.connectTimeout <= 0) ? 5000 : builder.connectTimeout.Value; this.readTimeout = (builder.readTimeout == null || builder.readTimeout <= 0) ? 10000 : builder.readTimeout.Value; try { string uriStr = string.IsNullOrEmpty(builder.credentialsURI) ? Environment.GetEnvironmentVariable("ALIBABA_CLOUD_CREDENTIALS_URI") : builder.credentialsURI; this.credentialsURI = new Uri(ParameterHelper.ValidateNotEmpty(uriStr, "credentialsURI", "Credentials URI must not be null or empty.")); } catch (UriFormatException) { throw new CredentialException("Credential URI is not valid."); } } public class Builder: SessionCredentialsProvider.Builder { internal string credentialsURI; internal int? connectTimeout; internal int? readTimeout; public Builder CredentialsURI(string credentialsURI) { this.credentialsURI = credentialsURI; return this; } public Builder CredentialsURI(Uri credentialsURI) { this.credentialsURI = credentialsURI.ToString(); return this; } public Builder ConnectTimeout(int? connectTimeout) { this.connectTimeout = connectTimeout; return this; } public Builder ReadTimeout(int? readTimeout) { this.readTimeout = readTimeout; return this; } public URLCredentialProvider Build() { return new URLCredentialProvider(this); } } public override string GetProviderName() { return "credentials_uri"; } public override RefreshResult<CredentialModel> RefreshCredentials() { CompatibleUrlConnClient client = new CompatibleUrlConnClient(); return CreateCredential(client); } public override async Task<RefreshResult<CredentialModel>> RefreshCredentialsAsync() { CompatibleUrlConnClient client = new CompatibleUrlConnClient(); return await CreateCredentialAsync(client); } private RefreshResult<CredentialModel> CreateCredential(IConnClient client) { return GetNewSessionCredentials(client); } private async Task<RefreshResult<CredentialModel>> CreateCredentialAsync(IConnClient client) { return await GetNewSessionCredentialsAsync(client); } private RefreshResult<CredentialModel> GetNewSessionCredentials(IConnClient client) { HttpRequest httpRequest = new HttpRequest(credentialsURI.ToString()); httpRequest.SetCommonUrlParameters(); httpRequest.Method = MethodType.GET; httpRequest.ConnectTimeout = connectTimeout; httpRequest.ReadTimeout = readTimeout; HttpResponse httpResponse; try { httpResponse = client.DoAction(httpRequest); } catch (Exception e) { throw new CredentialException("Failed to connect Server: " + credentialsURI.ToString() + e.ToString()); } if (httpResponse.Status >= 300 || httpResponse.Status < 200) { throw new CredentialException("Failed to get credentials from server: " + credentialsURI.ToString() + "\nHttpCode=" + httpResponse.Status + "\nHttpRAWContent=" + httpResponse.GetHttpContentString()); } Dictionary<string, string> map = JsonConvert.DeserializeObject<Dictionary<string, string>>(httpResponse.GetHttpContentString()); if (map.ContainsKey("Code") && DictionaryUtil.Get(map, "Code") == "Success") { string expirationStr = DictionaryUtil.Get(map, "Expiration").Replace('T', ' ').Replace('Z', ' '); var dt = Convert.ToDateTime(expirationStr); long expiration = dt.GetTimeMillis(); CredentialModel credentialModel = new CredentialModel { Expiration = expiration, Type = AuthConstant.CredentialsURI, ProviderName = GetProviderName() }; return new RefreshResult<CredentialModel>(credentialModel, GetStaleTime(expiration)); } throw new CredentialException(JsonConvert.SerializeObject(map)); } private async Task<RefreshResult<CredentialModel>> GetNewSessionCredentialsAsync(IConnClient client) { HttpRequest httpRequest = new HttpRequest(credentialsURI.ToString()); httpRequest.SetCommonUrlParameters(); httpRequest.Method = MethodType.GET; httpRequest.ConnectTimeout = connectTimeout; httpRequest.ReadTimeout = readTimeout; HttpResponse httpResponse; try { httpResponse = await client.DoActionAsync(httpRequest); } catch (Exception e) { throw new CredentialException("Failed to connect Server: " + credentialsURI.ToString() + e.ToString()); } if (httpResponse.Status >= 300 || httpResponse.Status < 200) { throw new CredentialException("Failed to get credentials from server: " + credentialsURI.ToString() + "\nHttpCode=" + httpResponse.Status + "\nHttpRAWContent=" + httpResponse.GetHttpContentString()); } Dictionary<string, string> map = JsonConvert.DeserializeObject<Dictionary<string, string>>(httpResponse.GetHttpContentString()); if (map.ContainsKey("Code") && DictionaryUtil.Get(map, "Code") == "Success") { string expirationStr = DictionaryUtil.Get(map, "Expiration").Replace('T', ' ').Replace('Z', ' '); var dt = Convert.ToDateTime(expirationStr); long expiration = dt.GetTimeMillis(); CredentialModel credentialModel = new CredentialModel { Expiration = expiration, Type = AuthConstant.CredentialsURI, ProviderName = GetProviderName() }; return new RefreshResult<CredentialModel>(credentialModel, GetStaleTime(expiration)); } throw new CredentialException(JsonConvert.SerializeObject(map)); } } }