You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用C# WSManConnectionInfo通过BasicAuthToOAuth连接Exchange Online失败

问题排查:C#通过WSManConnectionInfo连接Exchange Online(现代认证)失败

我们的代码原本使用WSManConnectionInfo类连接O365,此前采用Basic Auth,现租户已关闭Basic Auth,计划升级至现代认证。通过PowerShell可成功获取AccessToken并使用New-PSSession cmdlet连接,但C#实现相同逻辑时,打开Runspace抛出异常。

PowerShell 成功实现代码

Add-Type -Path 'C:\Program Files\WindowsPowerShell\Modules\AzureAD\2.0.2.140\Microsoft.IdentityModel.Clients.ActiveDirectory.dll'
 
$authContext45 = New-Object "Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext" -ArgumentList " https://login.windows.net/mytenant.onmicrosoft.com"
$secret = Get-ChildItem cert://localmachine/my/thumbprint
$CAC = [Microsoft.IdentityModel.Clients.ActiveDirectory.ClientAssertionCertificate]::new(appId,$secret)
$authenticationResult = $authContext45.AcquireTokenAsync("https://outlook.office365.com",$CAC)

$token = $authenticationResult.Result.AccessToken
$Authorization = "Bearer {0}" -f $Token
$Password = ConvertTo-SecureString -AsPlainText $Authorization -Force
$Ctoken = New-Object System.Management.Automation.PSCredential -ArgumentList "OAuthUser@tenantGUID",$Password
 
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/PowerShell-LiveId?BasicAuthToOAuthConversion=true -Credential $Ctoken -Authentication Basic -AllowRedirection -Verbose
Import-PSSession $Session

C# 失败实现代码

获取OAuth Token并创建连接信息

public static Collection<PSObject> GetUsersUsingOAuthPublic()
{
    var authContext = new AuthenticationContext("https://login.windows.net/mytenant.onmicrosoft.com");
    X509Store certStore = new X509Store(StoreName.My, StoreLocation.LocalMachine);

    certStore.Open(OpenFlags.ReadOnly);
    X509Certificate2Collection certCollection = certStore.Certificates.Find(X509FindType.FindByThumbprint, certThumbprint, false);
    certStore.Close();
    var cac = new ClientAssertionCertificate(appId, certCollection[0]);
    var authResult = authContext.AcquireTokenAsync("https://outlook.office365.com", cac);

    var token = authResult.Result.AccessToken;
    string auth = string.Format("Bearer {0}", token);
    System.Security.SecureString password = new System.Security.SecureString();

    foreach (char c in auth)
    {
        password.AppendChar(c);
    }

    PSCredential psCredential = new PSCredential(string.Format("OAuthUser@{0}", tenantId), password);

    WSManConnectionInfo connectionInfo = new WSManConnectionInfo(
        new Uri("https://outlook.office365.com/powershell-liveid?BasicAuthToOAuthConversion=true"),
        "https://schemas.microsoft.com/powershell/Microsoft.Exchange",
        psCredential
        );
    connectionInfo.AuthenticationMechanism = AuthenticationMechanism.Basic;
    connectionInfo.SkipCACheck = true;
    connectionInfo.SkipCNCheck = true;

    using (Runspace runspace = RunspaceFactory.CreateRunspace(connectionInfo))
    {
        return GetUserInformation(10, runspace);
    }
}

Runspace打开与命令执行逻辑

public static Collection<PSObject> GetUserInformation(int count, Runspace runspace)
{
    using (PowerShell powershell = PowerShell.Create())
    {
        powershell.AddCommand("Get-Users");
        powershell.AddParameter("ResultSize", count);
        runspace.Open();
        powershell.Runspace = runspace;
        return powershell.Invoke();
    }
}

抛出的异常信息

System.Management.Automation.Remoting.PSRemotingTransportException
HResult=0x80131501
Message=Connecting to remote server outlook.office365.com failed with the following error message : The WS-Management service cannot process the request. Cannot find the https://schemas.microsoft.com/powershell/Microsoft.Exchange session configuration in the WSMan: drive on the outlook.office365.com computer. For more information, see the about_Remote_Troubleshooting Help topic.

排查方向与解决办法

  • 补充重定向配置:PowerShell中使用了-AllowRedirection参数,C#的WSManConnectionInfo需要添加connectionInfo.AllowRedirection = true;,缺失该配置可能导致无法正确跳转至目标端点,找不到会话配置。
  • 修正命令拼写:C#中调用的Get-Users是错误的,Exchange Online的正确命令为Get-User(单数),虽然异常发生在Runspace打开阶段,但该错误可能影响后续会话初始化逻辑,建议先修正。
  • 验证认证头一致性:对比PowerShell与C#生成的PSCredential内容,确保Bearer token完整无截断。可在C#中输出token内容(仅调试用),与PowerShell中获取的token对比,确认手动构建SecureString时无字符遗漏。
  • 统一ADAL库版本:确保C#项目引用的Microsoft.IdentityModel.Clients.ActiveDirectory库版本与PowerShell中加载的2.0.2.140一致,版本差异可能导致token格式不兼容。
  • 检查权限与Token有效性:通过JWT解码工具检查获取的token,确认包含https://outlook.office365.com/.default的scope,且应用程序已被授予Exchange Online管理权限(如Exchange Administrator角色)。
  • 确认连接URI格式:确保连接URI中的BasicAuthToOAuthConversion=true参数未被编码错误修改,可直接复制PowerShell中使用的URI到C#代码中,避免手动输入导致的拼写错误。

内容的提问来源于stack exchange,提问作者onyx12

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 14:20:22