首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Exchange BasicAuthToOAuth不使用WSManConnectionInfo

Exchange BasicAuthToOAuth不使用WSManConnectionInfo
EN

Stack Overflow用户
提问于 2022-09-17 14:22:40
回答 2查看 210关注 0票数 0

我们的代码目前使用WSManConnectionInfo类连接到O365。我们使用基本的auth,并试图升级到现代的auth。我关闭了我的房客的基本公寓。按照本指南,https://www.michev.info/Blog/Post/2997/connecting-to-exchange-online-powershell-via-client-secret-fl...,我能够通过获取访问令牌并使用New cmdlet在PowerShell中成功连接。我使用以下命令:

代码语言:javascript
运行
复制
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# WSManConnectionInfo做同样的事情时,每当我试图打开运行空间时,我都会得到这个奇怪的错误:

System.Management.Automation.Remoting.PSRemotingTransportException HResult=0x80131501 Message=Connecting to remote server outlook.office365.com失败,出现以下错误消息:WS-管理服务无法处理请求。无法在outlook.office 365.com计算机上的https://schemas.microsoft.com/powershell/Microsoft.Exchange:WSMan:驱动器中找到WSMan会话配置。有关更多信息,请参见about_Remote_Troubleshooting帮助主题。以下是代码:

代码语言:javascript
运行
复制
    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);
        }
    }

我像这样打开运行空间:

代码语言:javascript
运行
复制
    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();
        }
    }

例外:异常图像

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-10-10 21:50:06

我们在这个问题上也一直在努力,我们能够让它发挥作用。在这个测试用例中,我们为accessToken使用了一个秘密,而不是一个证书,但这不重要。

第一个区别是uri应该如下所示:

代码语言:javascript
运行
复制
Uri psURI = new($"https://outlook.office365.com/powershell-liveid?BasicAuthToOAuthConversion=true&email=SystemMailbox%7bbb558c35-97f1-4cb9-8ff7-d53741dc928c%7d%40{msDomain}");

第二个更改是模式,通过此更改,您不会传递模式的完整url,只传递最后一部分:

代码语言:javascript
运行
复制
WSManConnectionInfo connectionInfo = new(psURI, "Microsoft.Exchange", psCredential)
{
    AuthenticationMechanism = AuthenticationMechanism.Basic,    
    SkipCACheck = true,
    SkipCNCheck = true
};

不是传递"https://schemas.microsoft.com/powershell/Microsoft.Exchange“,而是传递"Microsoft.Exchange”

下面是允许我们针对基本禁用的租户运行的完整代码:

代码语言:javascript
运行
复制
string clientId = "";
string tenantId = "";
string secret = "";
string upn = "user@yourdomain.com";
string msDomain = "YOURDOMAIN.onmicrosoft.com";


IConfidentialClientApplication thisApp = ConfidentialClientApplicationBuilder.Create(clientId)
    .WithClientSecret(secret)
    .WithAuthority($"https://login.windows.net/{msDomain}/")
    .Build();
AuthenticationResult accessToken = await thisApp.AcquireTokenForClient(new[] { $"https://outlook.office365.com/.default" }).ExecuteAsync();

//Bearer Header
string auth = $"Bearer {accessToken.AccessToken}";
SecureString password = GetSecureString(auth);

PSCredential psCredential = new($"OAuthUser@{tenantId}", password);

Uri psURI = new("https://outlook.office365.com/powershell-liveid?BasicAuthToOAuthConversion=true&email=SystemMailbox%7bbb558c35-97f1-4cb9-8ff7-d53741dc928c%7d%40lukydev.onmicrosoft.com");

WSManConnectionInfo connectionInfo = new(psURI, "Microsoft.Exchange", psCredential)
{
    AuthenticationMechanism = AuthenticationMechanism.Basic,    
    SkipCACheck = true,
    SkipCNCheck = true,
};

using Runspace runspace = RunspaceFactory.CreateRunspace(connectionInfo);
runspace.Open();
using PowerShell ps = PowerShell.Create();
ps.Runspace = runspace;

ps.AddCommand("Get-Mailbox");
ps.AddParameter("Identity", upn);

var results = await ps.InvokeAsync();
票数 0
EN

Stack Overflow用户

发布于 2022-09-19 08:36:04

据我所知,微软不支持这一点。要用MFA连接到Exchange,您应该使用这里描述的一种受支持的方法:https://learn.microsoft.com/en-gb/powershell/exchange/connect-to-exchange-online-powershell?view=exchange-ps

请检查我的答案,用一个无人值守的脚本形式使用证书拇指打印连接,这是最接近您想要实现的:使用证书和C#连接到Exchange联机

连接的其他选项是:

  • 使用基于浏览器的单点登录的交互式脚本
  • 基于设备的登录
  • 内联凭据

所有这些选项都在我上面的链接中描述。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73755642

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档