コード例 #1
0
        public static async Task <string> GetAccessTokenAsync(int accountId)
        {
            string accessToken = null;

            await DataAccess.ExecuteTransactionAsync(async (cnn, trn) => {
                using (SqlCommand cmd = new SqlCommand()
                {
                    CommandType = CommandType.Text,
                    CommandText = "select top 1 * from AzureAccount with(updlock,rowlock) where AccountId=@accountId",
                    Connection = cnn,
                    Transaction = trn,
                })
                {
                    cmd.Parameters.AddWithValue("@accountId", accountId);

                    DateTime?expiresOn             = null;
                    string clientId                = null, clientSecret = null, user = null, password = null, tenantId = null;
                    Models.AzureResources resource = Models.AzureResources.AzureResource_PowerBi;
                    await cmd.ExecuteReaderExtAsync((reader) =>
                    {
                        expiresOn    = reader.AsNullable <DateTime>("ExpiresOn");
                        accessToken  = reader.StringOrBlank("AccessToken").Trim();
                        resource     = reader.ValueOrDefault <Models.AzureResources>("Resource", Models.AzureResources.AzureResource_PowerBi);
                        clientId     = reader.StringOrBlank("ClientId");
                        clientSecret = reader.StringOrBlank("ClientSecret");
                        user         = reader.StringOrBlank("User");
                        password     = Encryptor.Current.Decrypt(reader.BytesOrNull("Password"));
                        tenantId     = reader.StringOrDefault("TenantId", null);
                        return(false);
                    });

                    if (string.IsNullOrWhiteSpace(accessToken) || !expiresOn.HasValue || expiresOn.Value < DateTime.UtcNow)
                    {
                        TokenInfo token = await Token.GetGrantTypePasswordAsync(
                            resource,
                            clientId,
                            clientSecret,
                            user,
                            password,
                            tenantId
                            );
                        using (SqlCommand cmdu = new SqlCommand()
                        {
                            CommandType = CommandType.Text,
                            CommandText = "update AzureAccount set AccessToken=@accessToken, ExpiresOn=@expiresOn where AccountId=@accountId",
                            Connection = cnn,
                            Transaction = trn,
                        })
                        {
                            cmdu.Parameters.AddWithValue("@accountId", accountId);
                            cmdu.Parameters.AddWithValue("@accessToken", token.AccessToken);
                            cmdu.Parameters.AddWithValue("@expiresOn", token.ExpiresOn.AddMinutes(-1)); // allow 1 minute to avoid issues
                            cmdu.ExecuteNonQuery();
                        }
                        accessToken = token.AccessToken;
                    }
                }
            });

            return(accessToken);
        }
コード例 #2
0
        public static async Task <TokenInfo> GetGrantTypePasswordAsync(
            Models.AzureResources _resource,
            string _clientId,
            string _clientSecret,
            string _user,
            string _password,
            string _tenantId = null
            )
        {
            TokenInfo token = null;

            List <KeyValuePair <string, string> > vals = new List <KeyValuePair <string, string> >();

            vals.Add(new KeyValuePair <string, string>("scope", "openid"));

            switch (_resource)
            {
            case Models.AzureResources.AzureResource_PowerBi:
                vals.Add(new KeyValuePair <string, string>("resource", "https://analysis.windows.net/powerbi/api"));        // TODO: move URL to config file
                break;

            default:
                throw new ApplicationException("Resource is required.");
            }

            if (string.IsNullOrWhiteSpace(_clientId))
            {
                throw new ApplicationException("Client ID is required.");
            }
            vals.Add(new KeyValuePair <string, string>("client_id", _clientId.Trim()));

            if (!string.IsNullOrWhiteSpace(_clientSecret))
            {
                vals.Add(new KeyValuePair <string, string>("client_secret", _clientSecret.Trim()));
            }

            vals.Add(new KeyValuePair <string, string>("grant_type", "password"));
            vals.Add(new KeyValuePair <string, string>("username", (_user ?? "").Trim()));
            vals.Add(new KeyValuePair <string, string>("password", (_password ?? "").Trim()));

            string url = string.Format("https://login.windows.net/{0}/oauth2/token", (_tenantId ?? "common").Trim());     // TODO: move URL to config file

            HttpClient          client   = new HttpClient();
            HttpResponseMessage response = await client.PostAsync(url, new FormUrlEncodedContent(vals));

            string responseData = "";

            using (Stream data = await response.Content.ReadAsStreamAsync())
                using (StreamReader reader = new StreamReader(data, System.Text.Encoding.UTF8))
                {
                    responseData = await reader.ReadToEndAsync();
                }

            if (!string.IsNullOrWhiteSpace(responseData))
            {
                JavaScriptSerializer jss = new JavaScriptSerializer();
                jss.RegisterConverters(new[] { new TokenInfoConverter() });
                if (response.IsSuccessStatusCode)
                {
                    token = jss.Deserialize <TokenInfo>(responseData);
                }
                else
                {
                    throw jss.Deserialize <AzureTokenException>(responseData);    // cannot throw from inside converter (different call context)
                }
            }

            return(token);
        }