将 Excel 连接到 Azure 上的 OAuth API

问题描述 投票:0回答:3

我们已通过 Azure AD(实现 OAuth 2.0)对多租户 SaaS 应用程序实施身份验证。 API 可通过 Angular SPA 访问,也可由其他客户端(例如具有专用客户端 ID 的注册 REST 客户端)访问。如果相关:我们使用授权代码流程。

在同一个应用程序上,我们有一个 OData API,我们希望通过它提供对用户应用程序(例如 Excel)的数据访问。由于我们是一个多租户应用程序,因此需要像访问“普通”Web API 时一样对连接进行身份验证,以便我们的数据层可以过滤该租户拥有的数据。

尽管我们只使用 Microsoft 服务(通过 Azure),但 Microsoft Excel 如何使用正确的身份验证方法连接到 OData 源似乎并不明显。我发现一篇文章解释了如何使用具有自定义连接定义的 Power Query 编辑器。我不会考虑这种方法,因为它对于典型的最终用户来说不是一个强大的解决方案。除了这种自定义配置方法之外,我还阅读了有关接管连接的商业第三方库的信息。然而,对于我的 SaaS 客户,我不能建议将此作为通用解决方案。
我还发现了另一篇文章,它使用 Azure 函数作为代理 API 来获取数据。对于最终用户来说,这似乎是一个强大的解决方案,但我不确定如何安全、正确地为正确的用户验证 API(本文中的示例专用于 1 个租户)。

问: 是否有强大的(开箱即用的)配置供最终用户从 Excel 访问经过 OAuth 验证的 OData feed/API?如果没有,我应该考虑哪些安全的替代方案?

excel azure oauth-2.0 azure-active-directory
3个回答
7
投票

您可以从客户端应用程序(例如 Excel、Word、Powerpoint 和 Publisher)在 AzureAD 上进行 OAuth 2.0 身份验证。这适用于打开整个文件(Office 2016 或更高版本)或从网页导入数据(Office 2019 / M365 应用程序)。

在 REST 客户端中使用 OAuth 身份验证时,设置 OAuth 身份验证的方式与常规且记录良好的 OAuth 流程略有不同。

而不是发送将客户端转发到 https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize 的标头 您需要返回http响应代码401(未经授权)并添加下一个标头:

WWW-Authenticate: Bearer resource="https://management.azure.com/" client_id="{the client id of your registered app in Azure AD}", trusted_issuers="00000001-0000-0000-c000-000000000000@*", token_types="app_asserted_user_v1 service_asserted_app_v1", authorization_uri="https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize",Basic Realm=""'

在 Azure AD 中您的应用程序注册中:

  • API权限中:
    • Azure Active Directory 图形 > 用户.读取 在
  • 公开API:
    • 添加范围:https://{fqdn of your api}/email(电子邮件或用于身份验证的其他属性)
    • 授权客户端应用 > 添加客户端应用:d3590ed6-52b3-4102-aeff-aad2292ab01c(MS Office的ID)

注意:所有这些都没有记录在案。我通过嗅探 Outlook 和 O365 之间的流量发现了标头。

顺便说一句:如果您使用 webdav 协议提供文件:从网页中打开 Excel 文件可以很好地使用 javascript:

location.href = "ms-excel:ofe|https://{yourAPI}/your_output.xlsx"

6
投票

答案已编辑为最终工作版本

部分感谢其他人对此线程的评论,我已经能够使其正常工作。这是我的最终解决方案(根据原始答案编辑,缺少一些拼图)

我在 Azure 中注册了应用程序,公开了 API,将应用程序 ID URI 更改为我验证的应用程序 url 并添加了 user_impersonation 范围。

您需要确保您在 Azure AD 中拥有经过验证的自定义域名。

我接受了默认的 API 权限。

我创建了一个.net 6 WebApi项目,制作了一个简单的odata控制器。

[Route("odata")]
public class WBSController : BaseODataController
{
    public WBSController(IDbContextFactory<TableDbContext> db) : base(db)
    {

    }

    [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
    [EnableQuery]
    [HttpGet("WBS")]
    public IQueryable<WBS> Get()
    {
        IQueryable<WBS> ret = Db.WBS;

        return ret;
    }
}

然后我在 Program.cs 中配置了 API。 (注意:对于客户端 ID - 使用您的应用程序 ID Uri。

程序.cs

.AddMicrosoftIdentityWebApi(
     opt => //JwtBearerOptions
    {
        opt.Audience = "[Your App Id Uri eg. acme.com.au]";
        opt.Events = new JwtBearerEvents()
        {
            OnChallenge = async ctxv =>  
            {
                opt.Challenge =
                    @"Bearer  realm="""", client_id=""[Your App Id Uri]"", trusted_issuers=""00000001-0000-0000-c000-000000000000@*"", token_types=""app_asserted_user_v1 service_asserted_app_v1"",  authorization_uri=""https://login.microsoftonline.com/[Your Tenant Id]/oauth2/v2.0/authorize""";  //This is the magic that forces the Microsoft login dialog to open
            }
        };
    },
    opt =>   //MicrosoftIdentityOptions
    {
        opt.Instance = "https://login.microsoftonline.com/";
        opt.ClientId = "[Your App Id Uri]";
        opt.TenantId = "common";
    },
    $"{JwtBearerDefaults.AuthenticationScheme}"  //Scheme Name
);

我认为这是一个很大的突破,因为我能够选择一个帐户并登录。

如果您遇到以下错误,则表示您尚未将 Azure AD 中的 App ID 设置为已验证的应用程序 url: invalid_resource:AADSTS500011: 在名为 .. 的租户中找不到资源主体 ...... ...

如果出现任何错误,或者没有执行任何操作,请使用 Fiddler 运行跟踪。这就是我确定它正在寻找 user_impersonation 范围的方式。

如果所有这些步骤都正确完成,您最终应该在 Excel 中得到一个可刷新的 OData 数据表。

我注意到微软表示不支持连接到这样的“任意”服务。 https://learn.microsoft.com/en-us/power-query/connectors/odatafeed#authenticating-to-任意-services

但是我相信这是为 Excel 超级用户提供从 Web Api 访问结构化数据的能力的一个非常好的方法。我希望这篇文章可以为您节省我花在做这件事上的时间。


0
投票

嗨@MotKohn 你是如何成功地与 localhos 合作的?

谢谢

© www.soinside.com 2019 - 2024. All rights reserved.