繁体   English   中英

使用 ASP.Net 将文件上传到 OneDrive Web Forms

[英]Upload File to OneDrive using ASP.Net Web Forms

我创建了一个简单的 ASP.Net web forms 应用程序,并希望将文件上传到 One Drive。 为此,我实现了 MS Graph API。 共有三个文件,Upload.aspx、Upload.aspx.cs、MsalAuthentication.cs(下面也给出了代码)。 当我单击“上传按钮”时,控件转到:

var result = await _clientApplication.AcquireTokenByUsernamePassword(_scopes, _username, _password).ExecuteAsync(); ,它卡在这里并且不会移动到下一个语句。

在 web.Config 文件中,我还将 applicationId 和tenantId 指定为:

< appSettings >
      < add key="tenantId" value="some id" />
      < add key="applicationId" value="some id" />
   < /appSettings>

谁能告诉我这个问题? 代码如下

上传.aspx.cs

using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
using System.Security;
using Microsoft.Identity.Client;
using Microsoft.Graph;
using Microsoft.Extensions.Configuration;
using Helpers;
using System.Configuration;
using System.Collections.Specialized;

namespace WebFormsOneDrive
{
    public partial class Upload : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }

        protected void Button1_Click(object sender, EventArgs e)
        {
            var config = LoadAppSettings();
            if (config == null)
            {
                Console.WriteLine("Invalid appsettings.json file.");
                return;
            }

            var userName = ReadUsername();
            var userPassword = ReadPassword();

            var client = GetAuthenticatedGraphClient(config, userName, userPassword);

            // request 1 - upload small file to user's onedrive
            var fileName = FileUpload1.FileName;
            var filePath = Path.Combine(@"D:\webform\upload\", fileName);
            

            FileStream fileStream = new FileStream(filePath, FileMode.Open);
            var uploadedFile = client.Me.Drive.Root
                                          .ItemWithPath(fileName)
                                          .Content
                                          .Request()
                                          .PutAsync<DriveItem>(fileStream)
                                          .Result;
            Console.WriteLine("File uploaded to: " + uploadedFile.WebUrl);
        }
        private static NameValueCollection LoadAppSettings()
        {
            try
            {
                //var config = new ConfigurationBuilder()
                //                  .SetBasePath(System.IO.Directory.GetCurrentDirectory())
                //                  .AddXMLFile("Web.config", false, true)
                //                  .Build();
                var config = ConfigurationManager.GetSection("appSettings") as NameValueCollection;
                if (string.IsNullOrEmpty(config["applicationId"]) ||
                    string.IsNullOrEmpty(config["tenantId"]))
                {
                    return null;
                }

                return config;
            }
            catch (System.IO.FileNotFoundException)
            {
                return null;
            }
        }

        private static IAuthenticationProvider CreateAuthorizationProvider(NameValueCollection config, string userName, SecureString userPassword)
        {
            var clientId = config["applicationId"];
            var authority = $"https://login.microsoftonline.com/{config["tenantId"]}/v2.0";

            List<string> scopes = new List<string>();
            scopes.Add("User.Read");
            scopes.Add("Files.Read");
            scopes.Add("Files.ReadWrite");
            var cca = PublicClientApplicationBuilder.Create(clientId)
                                                    .WithAuthority(authority)
                                                    .Build();
            return MsalAuthenticationProvider.GetInstance(cca, scopes.ToArray(), userName, userPassword);
        }

        private static GraphServiceClient GetAuthenticatedGraphClient(NameValueCollection config, string userName, SecureString userPassword)
        {
            var authenticationProvider = CreateAuthorizationProvider(config, userName, userPassword);
            var graphClient = new GraphServiceClient(authenticationProvider);
            return graphClient;
        }

        private static SecureString ReadPassword()
        {
            //Console.WriteLine("Enter your password");
            //SecureString password = new SecureString();
            //while (true)
            //{
            //    ConsoleKeyInfo c = Console.ReadKey(true);
            //    if (c.Key == ConsoleKey.Enter)
            //    {
            //        break;
            //    }
            //    password.AppendChar(c.KeyChar);
            //    Console.Write("*");
            //}
            //Console.WriteLine();
            var password = new SecureString();
            password.AppendChar('p');
            password.AppendChar('a');
            password.AppendChar('s');
            password.AppendChar('s');
            password.AppendChar('w');
            password.AppendChar('o');
            password.AppendChar('r');
            password.AppendChar('d');
            return password;
        }

        private static string ReadUsername()
        {
            //string username;
            //Console.WriteLine("Enter your username");
            //username = Console.ReadLine();
            //return username;
            string userName = "abcd@domain@onmicrosoft.com";
            return userName;
        }
    }
}

MsalAuthentication.cs

using System.Net.Http;
using System.Net.Http.Headers;
using System.Security;
using System.Threading.Tasks;
using Microsoft.Identity.Client;
using Microsoft.Graph;

namespace Helpers
{
    public class MsalAuthenticationProvider : IAuthenticationProvider
    {
        private static MsalAuthenticationProvider _singleton;
        private IPublicClientApplication _clientApplication;
        private string[] _scopes;
        private string _username;
        private SecureString _password;
        private string _userId;

        private MsalAuthenticationProvider(IPublicClientApplication clientApplication, string[] scopes, string username, SecureString password)
        {
            _clientApplication = clientApplication;
            _scopes = scopes;
            _username = username;
            _password = password;
            _userId = null;
        }

        public static MsalAuthenticationProvider GetInstance(IPublicClientApplication clientApplication, string[] scopes, string username, SecureString password)
        {
            if (_singleton == null)
            {
                _singleton = new MsalAuthenticationProvider(clientApplication, scopes, username, password);
            }

            return _singleton;
        }

        public async Task AuthenticateRequestAsync(HttpRequestMessage request)
        {
            var accessToken = await GetTokenAsync();

            request.Headers.Authorization = new AuthenticationHeaderValue("bearer", accessToken);
        }

        public async Task<string> GetTokenAsync()
        {
            if (!string.IsNullOrEmpty(_userId))
            {
                try
                {
                    var account = await _clientApplication.GetAccountAsync(_userId);

                    if (account != null)
                    {
                        var silentResult = await _clientApplication.AcquireTokenSilent(_scopes, account).ExecuteAsync();
                        return silentResult.AccessToken;
                    }
                }
                catch (MsalUiRequiredException) { }
            }

            var result = await _clientApplication.AcquireTokenByUsernamePassword(_scopes, _username, _password).ExecuteAsync();
            _userId = result.Account.HomeAccountId.Identifier;
            return result.AccessToken;
        }

我认为你混合了两个概念:

  • 代表用户的连接访问(例如通过 AAD)
  • 通过应用程序的安全性访问(客户端密码)

一般来说,我们不能像这样将用户的密码清楚地传递给 API,我们玩的是令牌。

适用于所有场景的 Graph Doc

向您的 AAD 添加一个客户端密码,并将您需要的所有角色库提供给您的 api。

如果您使用凭据流,则不应在图形调用中使用“我”,而应使用类似:graph.Users["user@email.com"].Drive....

否则,如果您真的想使用密码,您可以这样做:

IPublicClientApplication publicClientApplication = PublicClientApplicationBuilder
            .Create(clientId)
            .WithTenantId(tenantID)
            .Build();

UsernamePasswordProvider authProvider = new UsernamePasswordProvider(publicClientApplication, scopes);

GraphServiceClient graphClient = new GraphServiceClient(authProvider);

User me = await graphClient.Me.Request()
                .WithUsernamePassword(email, password)
                .GetAsync();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM