![](/img/trans.png)
[英]Are there high-availability options for On-premise applications using Azure
[英]Querying On-premise SharePoint using Azure AD MFA through C# app
我正在尝试使用 Microsoft.Identity.Client 和 Microsoft.SharePoint.Client 库对本地 SharePoint 服务器进行身份验证,然后对其进行查询。
我获得 Azure AD 访问令牌,其中 SharePoint 服务器是以下内容的一部分:
private readonly string[] m_scopes = { "user.read", "https://sql.azuresynapse-dogfood.net/user_impersonation" };
var publicAppBuilder = PublicClientApplicationBuilder.Create("MyClientId").WithAuthority("https://login.microsoftonline.com/a******com.onmicrosoft.com");
publicAppBuilder.WithRedirectUri("https://login.microsoftonline.com/common/oauth2/nativeclient");
var app = publicAppBuilder.Build();
AuthenticationResult result = null;
result = app.AcquireTokenInteractive(m_scopes).ExecuteAsync().GetAwaiter().GetResult();
if (result != null)
{
m_mediator.AccessToken = result.AccessToken;
}
当我获得访问令牌时,我将其放入请求 header 中,如下所示:
args.WebRequestExecutor.RequestHeaders["Authorization"] = "Bearer " + m_mediator.AccessToken;
在ClientContext.ExecutingWebRequest
订阅方法中:
clientContext.ExecutingWebRequest += (sender, args) =>
这是由
context.ExecuteQuery();
远程服务器返回错误:(401) 未经授权。 或远程服务器返回错误:(403) 禁止访问。
如何建立连接? 我想避免使用仅应用程序注册,我想使用 Azure AD MFA(交互式)方法进行身份验证。请注意,我拥有所需的所有权限,并且我是 Azure AD 的管理员,其中加入了 SharePoint,以及SharePoint 服务器本身。 我通过浏览器进行身份验证就好了。
到目前为止,我已经尝试了多种方法:
我尝试创建一个单独的请求,在其中我将之前获取的 accessToken 转发为 Authorization: Bearer token
我尝试从身份验证连接 window 读取 FedAuth,因此我可以在我的 HTTP 请求中转发它,但没有成功
我尝试使用 WebBrowser C# class 创建一个“Web 浏览器”,并读取浏览器级别的 cookies,如下所示: cookieContainer = webBrowser1.Document.Cookie;
但我没有成功。
我希望通过 Azure AD 进行身份验证,然后连接到 SharePoint 以查询它
要解决错误“远程服务器返回错误:(401) 未经授权”,请尝试检查以下内容:
SharePoint在线URL必须始终以HTTPS开头。
$SiteURL` `=` `"https://crescent.sharepoint.com/sites/marketing"`
检查您是否有足够的权限,以及您是否能够在浏览器中打开该网站。 确保拥有 SharePoint 在线管理员角色。
如果未启用,请确保在您的租户中启用旧版身份验证协议。
参考: SharePoint 在线:修复PowerShell中的“远程服务器返回错误(401)未授权”错误 - SharePoint日记
要解决错误“远程服务器返回错误:(403) 禁止访问。”,请尝试检查以下内容:
确保您是否提供了正确的 URL 和凭据。
请确认您是否安装了最新版本的SharePoint在线客户端组件SDK。
尝试明确地将自己添加到网站
检查您站点的锁定状态,如果锁定则解锁。
请检查您的租户中是否启用了任何条件访问策略。
如果您尝试连接到 Tenant Admin 站点,请确保 Tenant Admin URL 如下所示:
https://YourDomain-admin.sharepoint.com
参考: SharePoint 在线:修复“远程服务器返回错误:(403)禁止访问。” PowerShell - SharePoint 日记中的错误。
我找到了解决方案。
每当浏览器浏览新页面时,我基本上遍历所有 cookies 并解析所有 cookies 直到我获得 fedAuth cookie:
我从 System.Windows.Forms.WebBrowser 创建了一个 web 浏览器
在Navigated
的WebBrowserNavigatedEventHandler
中,我执行以下操作:
如果 (webBrowser1.Url.AbsoluteUri == "about:blank") { 返回; }
var cookieData = GetWebBrowserCookie.GetCookieInternal(webBrowser1.Url, false);
if (string.IsNullOrEmpty(cookieData) == false) { var dict = ParseCookieData(cookieData); 如果 (dict.ContainsKey("FedAuth") &&.string.IsNullOrEmpty(dict["FedAuth"])) { m_mediator;FedAuthCookie = dict["FedAuth"]。 如果 (dict.ContainsKey("rtFa") &&.string;IsNullOrEmpty(dict["rtFa"])) { m_mediator.RtFaCookie = dict["rtFa"]; } m_mediator.UpdateConfiguration(); 这个。关闭(); } }
ParseCookieData 方法如下所示:
private IDictionary<string, string> ParseCookieData(string cookieData)
{
var cookieDictionary = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
if (string.IsNullOrEmpty(cookieData))
{
return cookieDictionary;
}
var values = cookieData.TrimEnd(';').Split(';');
foreach (var parts in values.Select(c => c.Split(new[] { '=' }, 2)))
{
var cookieName = parts[0].Trim();
var cookieValue = parts.Length == 1 ? string.Empty : parts[1];
cookieDictionary[cookieName] = cookieValue;
}
return cookieDictionary;
}
和 GetWebBrowserCookie class 看起来像这样:
[SecurityCritical]
public static string GetCookieInternal(Uri uri, bool throwIfNoCookie)
{
uint pchCookieData = 0;
string url = UriToString(uri);
uint flag = (uint)NativeMethods.InternetFlags.INTERNET_COOKIE_HTTPONLY;
//Gets the size of the string builder
if (NativeMethods.InternetGetCookieEx(url, null, null, ref pchCookieData, flag, IntPtr.Zero))
{
pchCookieData++;
StringBuilder cookieData = new StringBuilder((int)pchCookieData);
//Read the cookie
if (NativeMethods.InternetGetCookieEx(url, null, cookieData, ref pchCookieData, flag, IntPtr.Zero))
{
DemandWebPermission(uri);
return cookieData.ToString();
}
}
int lastErrorCode = Marshal.GetLastWin32Error();
if (throwIfNoCookie || (lastErrorCode != (int)NativeMethods.ErrorFlags.ERROR_NO_MORE_ITEMS))
{
throw new Win32Exception(lastErrorCode);
}
return null;
}
private static void DemandWebPermission(Uri uri)
{
string uriString = UriToString(uri);
if (uri.IsFile)
{
string localPath = uri.LocalPath;
new FileIOPermission(FileIOPermissionAccess.Read, localPath).Demand();
}
else
{
new WebPermission(NetworkAccess.Connect, uriString).Demand();
}
}
private static string UriToString(Uri uri)
{
if (uri == null)
{
return string.Empty;
}
UriComponents components = (uri.IsAbsoluteUri ? UriComponents.AbsoluteUri : UriComponents.SerializationInfoString);
return new StringBuilder(uri.GetComponents(components, UriFormat.SafeUnescaped), 2083).ToString();
}
通过这种方式,我们打开一个弹出窗口 C# web 浏览器,使用 MFA 通过 web 对用户进行身份验证,然后在我们获取身份验证 cookie 时关闭浏览器,以便我们可以继续处理 HTTP 对 Sharepoint 服务器的请求。
来源: https://github.com/OceanAirdrop/SharePointOnlineGetFedAuthAndRtfaCookie
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.