使用VBA获取Graph API的访问令牌

时间:2017-06-24 17:35:55

标签: vba excel-vba excel

这是我第一次尝试调用Graph API(使用VBA),但我仍然无法获得一个访问令牌。 虽然我已阅读文档,但我不知道在不强制用户登录的情况下我需要申请哪些流程来获取访问令牌。这可以在我的OneDrive个人帐户上使用吗?

这是我试过的

Sub Test_GetToken()

    Dim xml As New MSXML2.XMLHTTP60
    Dim url As String

    url = "https://login.microsoftonline.com/namelles_test@outlook.com/oauth2/v2.0/token"

    url = url & "?client_id=eca0b14c-1154-4768-8e45-2cb5639b7e0d"
    url = url & "grant_type=client_credentials"
    url = url & "&client_secret=VksZ8FeDF5XiRfqTBsgs628"
    url = url & "&resource=https://graph.microsoft.com"

    xml.Open "POST", url, False
    xml.setRequestHeader "application", "x-www-form-urlencoded"


    xml.send ("")
    Debug.Print "status=" & xml.Status, "readyState=" & xml.readyState

    Debug.Print xml.responseText

    Set xml = Nothing

End Sub

我创建了一个仅用于测试的帐户(用户名:nameless_test@outlook.com,userpass:nameless1234)。因此,可以使用真实凭证。 有人可以告诉我需要应用的流程以及请求的构建方式吗? 提前致谢

1 个答案:

答案 0 :(得分:0)

您似乎错误地将电子邮件放入了代码中。

using System;
using System.Collections.Generic;
//
using System.Runtime.InteropServices;
using System.IO;
//

namespace TestFileDelete
{
    class FileDelete
    {
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        struct WIN32_FIND_DATAW
        {
            public FileAttributes dwFileAttributes;
            public System.Runtime.InteropServices.ComTypes.FILETIME ftCreationTime;
            public System.Runtime.InteropServices.ComTypes.FILETIME ftLastAccessTime;
            public System.Runtime.InteropServices.ComTypes.FILETIME ftLastWriteTime;
            public UInt32 nFileSizeHigh;  //  DWORD
            public UInt32 nFileSizeLow;  //  DWORD
            public UInt32 dwReserved0;    //  DWORD
            public UInt32 dwReserved1;  //  DWORD
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
            public String cFileName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
            public String cAlternateFileName;
        };


        static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);

        [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        private static extern IntPtr FindFirstFileW(String lpFileName, out WIN32_FIND_DATAW lpFindFileData);

        [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        private static extern Boolean FindNextFileW(IntPtr hFindFile, out WIN32_FIND_DATAW lpFindFileData);

        [DllImport("kernel32.dll")]
        private static extern Boolean FindClose(IntPtr handle);

        [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        public static extern Boolean DeleteFileW(String lpFileName);    //  Deletes an existing file

        [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        private static extern Boolean RemoveDirectoryW(String lpPathName);   //  Deletes an existing empty directory


        //  This method check to see if the given folder is empty or not.
        public static Boolean IsEmptyFolder(String folder)
        {
            Boolean res = true;

            if (folder == null && folder.Length == 0)
            {
                throw new Exception(folder + "is invalid");
            }

            WIN32_FIND_DATAW findFileData;
            String searchFiles = folder + @"\*.*";
            IntPtr searchHandle = FindFirstFileW(searchFiles, out findFileData);
            if (searchHandle == INVALID_HANDLE_VALUE)
            {
                throw new Exception("Cannot check folder " + folder);
            }

            do
            {
                if ((findFileData.dwFileAttributes & FileAttributes.Directory) == FileAttributes.Directory)
                {
                    //  found a sub folder
                    if (findFileData.cFileName != "." && findFileData.cFileName != "..")
                    {
                        res = false;
                        break;
                    }

                }   //  if ((findFileData.dwFileAttributes & FileAttributes.Directory) == FileAttributes.Directory)
                else
                {
                    //  found a file
                    res = false;
                    break;
                }
            } while (FindNextFileW(searchHandle, out findFileData));

            FindClose(searchHandle);
            return res;
        }   //  public static Boolean IsEmptyFolder(String folder)

        //  This method deletes the given folder
        public static Boolean DeleteFolder(String folder)
        {
            Boolean res = true;
            //  keep non-empty folders to delete later (after we delete everything inside)
            Stack<String> nonEmptyFolder = new Stack<String>();
            String currentFolder = folder;
            do
            {
                Boolean isEmpty = false;
                try
                {
                    isEmpty = IsEmptyFolder(currentFolder);
                }
                catch (Exception ex)
                {
                    //  Something wrong
                    res = false;
                    break;
                }

                if (!isEmpty)
                {
                    nonEmptyFolder.Push(currentFolder);
                    WIN32_FIND_DATAW findFileData;
                    IntPtr searchHandle = FindFirstFileW(currentFolder + @"\*.*", out findFileData);
                    if (searchHandle != INVALID_HANDLE_VALUE)
                    {
                        do
                        {   //  for each folder, find all of its sub folders and files
                            String foundPath = currentFolder + @"\" + findFileData.cFileName;
                            if ((findFileData.dwFileAttributes & FileAttributes.Directory) == FileAttributes.Directory)
                            {
                                //  found a sub folder
                                if (findFileData.cFileName != "." && findFileData.cFileName != "..")
                                {
                                    if (IsEmptyFolder(foundPath))
                                    {   //  found an empty folder, delete it
                                        if (!(res = RemoveDirectoryW(foundPath)))
                                        {
                                            Int32 error = Marshal.GetLastWin32Error();
                                            break;
                                        }
                                    }
                                    else
                                    {   //  found a non-empty folder
                                        nonEmptyFolder.Push(foundPath);
                                    }
                                }   //  if (findFileData.cFileName != "." && findFileData.cFileName != "..")

                            }   //  if ((findFileData.dwFileAttributes & FileAttributes.Directory) == FileAttributes.Directory)
                            else
                            {
                                //  found a file, delete it
                                if (!(res = DeleteFileW(foundPath)))
                                {
                                    Int32 error = Marshal.GetLastWin32Error();
                                    break;
                                }
                            }

                        } while (FindNextFileW(searchHandle, out findFileData));

                        FindClose(searchHandle);

                    }   //  if (searchHandle != INVALID_HANDLE_VALUE)

                }//  if (!IsEmptyFolder(folder))
                else
                {
                    if (!(res = RemoveDirectoryW(currentFolder)))
                    {
                        Int32 error = Marshal.GetLastWin32Error();
                        break;
                    }
                }

                if (nonEmptyFolder.Count > 0)
                {
                    currentFolder = nonEmptyFolder.Pop();
                }
                else
                {
                    currentFolder = null;
                }
            } while (currentFolder != null && res);

            return res;
        }   //  public static Boolean DeleteFolder(String folder)
    };

    class Program
    {
        static void Main(string[] args)
        {
            DateTime t1 = DateTime.Now;

            try
            {
                Boolean b = FileDelete.DeleteFolder(@"d:\test1");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

            DateTime t2 = DateTime.Now;
            TimeSpan ts = t2 - t1;
            Console.WriteLine(ts.Seconds);

        } 
    } 
}

应该是:

url = "https://login.microsoftonline.com/namelles_test@outlook.com/oauth2/v2.0/token"

此外,根据您的评论,您似乎必须将url = "https://login.microsoftonline.com/nameless_test@outlook.com/oauth2/v2.0/token" 放在请求正文中而不是URL中的查询参数。

grant_type