【问题标题】:Under which account a .net console application which is hosted inside Azure Function app, will be running托管在 Azure Function 应用程序中的 .net 控制台应用程序将在哪个帐户下运行
【发布时间】:2018-09-10 23:09:09
【问题描述】:

我开发了一个具有以下主要特征的 .net 控制台应用程序:-

  1. 与 SharePoint online REST API 集成,以检索一些列表项,并修改项目字段。
  2. 例如每天凌晨 1 点运行。
  3. 我将在 Azure Function 应用程序中托管此控制台应用程序。
  4. Azure 帐户对 sharepoint 租户没有任何权限,因为 Azure 帐户和 sharepoint online 位于不同的域中。

所以我不确定控制台应用程序将在哪个帐户下运行?

  • 它会在当前 Azure 帐户下运行吗?如果是这种情况,那么这将不起作用,因为 azure 帐户位于不同的域上并且对共享点没有任何权限(它不应该有)?

  • 我可以为 Azure 函数应用定义一个服务帐户以在其下运行,在这种情况下,我可以将服务帐户定义为在线共享点内的授权帐户?

  • 我需要在控制台应用程序中定义用户名/密码吗?我不喜欢接近,因为我将在控制台应用程序中公开密码。还要更改用户名的密码,这意味着我们需要相应地更新控制台应用程序..

请问有人可以就此提出建议吗? 谢谢

编辑

用于管理控制台应用程序身份验证的代码:-

using System; 

using System.Collections.Generic; 

using System.Linq; 

using System.Text; 

using Microsoft.SharePoint.Client; 



namespace O365SPProject 

{ 

    class Program 

    { 





     private class Configuration 

        { 

                public static string ServiceSiteUrl = "https://<tenant>.sharepoint.com"; 

                public static string ServiceUserName = "<user>@<tenant>.onmicrosoft.com"; 

                public static string ServicePassword = "xxxxxxxxxx"; 

        } 



                 static ClientContext GetonlineContext() 

                          { 

                                    var securePassword = new SecureString(); 

                                    foreach (char c in Configuration.ServicePassword) 

                                    { 

                                        securePassword.AppendChar(c); 

                                    } 

                                    var onlineCredentials = new SharePointOnlineCredentials(Configuration.ServiceUserName, securePassword); 

                                    var context = new ClientContext(Configuration.ServiceSiteUrl); 

                                    context.Credentials = onlineCredentials; 

                                    return context; 

                          } 





        static void Main(string[] args) 

        { 

            var ClientContext=GetonlineContext(); 

            Web web = clientContext.Web;  

            // do somethings            

        } 

    } 

}

【问题讨论】:

  • 嗨,john,您可以参考以下链接:sharepoint.stackexchange.com/questions/83985/…
  • @YukiLou-MSFT 感谢您的链接。但似乎我没有正确解释我的问题。现在我很清楚我可以在我的控制台应用程序中定义身份验证,主要是在ClientContext() 中。但我要问的是避免在控制台应用程序本身中定义用户名和密码,以及是否可以定义服务帐户(类似于我们在 Windows 任务调度程序中对任务进行身份验证的方式)+我默认情况下询问的是哪个帐户 Azure 功能将运行?在 azure 帐户用户名下?
  • 您的 Sharepoint Online 是否链接到您的 Azure AD ????
  • @Thomas 是的,它是一个连接到 Azure AD 的在线共享点。但是这有什么重要性?
  • 作为 MSI 的替代方案,在 Azure AD 中显式注册的应用程序可用于标识目的。有一个很好的博客系列描述了详细的步骤。它值得一看,但有一些微软已经指出的限制。我已编辑答案以包含此选项并将其与其他选项进行比较。

标签: azure sharepoint office365 azure-functions


【解决方案1】:

你的问题有多个部分,所以我会相应地回答。

1。您提到的 3 个选项中的哪个选项(或者如果有其他更好的选项:)),您应该使用哪个选项来管理您的配置数据/服务帐户身份

选项 4(类似于您的选项 2,但有细微差别): 您应该将您的服务帐户身份和配置数据完全从控制台应用程序中取出,并通过 Azure Function App 的“应用程序设置”将它们传入。

此选项类似于您在问题中的选项 2,因为您将信息保留在控制台应用程序代码之外

我可以为 Azure 函数应用定义一个服务帐户以在其下运行 它,在这种情况下,我可以将服务帐户定义为 在线共享点内的授权帐户?

但不同之处在于我并不是说您将能够为您的 Azure 函数应用程序定义一个服务帐户以在其下运行(因为您无法控制 Azure 函数将在其下运行的帐户,Microsoft 基础架构会负责它),而是将其作为安全配置数据传递给控制台应用程序,您的控制台应用程序将使用它。稍后在比较选项时详细了解安全性/加密。

实际上,我从问题中获取了您的控制台应用程序代码,创建了一个控制台应用程序并在计时器触发的 Azure 函数中使用它以使其正常工作。所以这些步骤来自一个工作样本。我在我的控制台应用程序中使用了“Microsoft.SharePointOnline.CSOM”nuget 包,并且必须上传一些依赖 dll 和 exe 才能运行。如果遇到问题,请随时询问有关执行此部分的更多详细信息。

添加应用程序设置 - 导航您的 Azure Function App 并单击“应用程序设置”

为您想要从控制台应用程序中取出并从外部控制的所有项目添加设置。我为我看到的所有 3 个项目都做了这件事,但这取决于你。

然后更改您的代码以使用这些设置。我已经在最后展示了确切的代码更改。

选项 5 在 Azure AD 中注册一个新应用程序来代表您的 Azure 函数。

  • 您应该在 Azure AD 中注册一个新应用程序并使用此身份在线访问 SharePoint。
  • 您需要为此应用程序授予 SharePoint Online 权限(注意:权限分配不会像您的服务帐户方法那样精细或详细,我将在比较选项时进行更多解释)
  • 您需要将证书与您的 AzureAD 应用程序相关联以帮助进行身份验证。
  • 在对 SharePoint Online 进行身份验证时,您将无法像现在在代码中那样直接使用 SharePointOnlineCredentials 类,而是在 http 请求的“授权”标头中发送不记名令牌。

这里是blog post,其中介绍了此选项 5 中涉及的详细步骤。 注意:该博客最后仍然在功能代码中省略了证书详细信息,例如密码,这并不理想,您需要将其移出应用程序设置或 Azure Key Vault。

2。 .NET 控制台应用程序将在哪个帐户下运行以及所有选项的快速比较

这是一个任意的 IIS 应用程序池帐户,正如 @Mitch Stewart 所指出的,其他 SO 帖子,并且在我为我的函数获得的输出中很明显,它在我的运行中的确切值是“IIS APPPOOL\mawsFnPlaceholder0_v1” .请参阅底部的图像。你已经分享了一些很好的信息,所以我不会重复。我唯一要补充的是,此帐户将由托管您的函数应用程序的基础架构控制,并且将更多地用于处理许多函数应用程序可以运行的共享基础架构中的隔离/其他问题,因此尝试控制/更改这可能不是现在要走的路。

选项 1(来自您的问题)- 为您的 SharePoint Online 网站授予 IIS 应用程序池帐户权限,尤其是当您不控制该帐户时可能不是一个好主意。

选项 2(来自您的问题)- 它会比您提到的其他 2 个选项更好,但您无法真正控制此帐户。

选项 3(来自您的问题)- 将此信息深入嵌入控制台应用程序将是一个维护问题,并且不是最安全的选项,除非您从保险库等开始阅读。无论您做什么,维护问题都将存在因为它嵌入在编译后的代码中,这是不应该的。

选项 4 - 这比之前的 3 个选项要好,因为它将代码的关注点与配置和身份信息分开,更新不需要重新编译。另请注意,您在应用程序设置配置中存储的任何内容默认情况下都是加密的(具有良好的密钥轮换管理),并且是推荐的方式。这些值仅在您的应用程序执行之前被解密并加载到进程内存中。查看此链接中的详细讨论,我还在下面给出了一个相关的小摘录-

Provide documentation about encrypt/decrypt settings

即使使用此选项,您也可以将它们存储在密钥保管库中,然后您的设置将是具有实际信息的密钥保管库机密的 URL。

选项 5 - 此选项利用基于 Azure AD 的身份向 SharePoint Online 进行身份验证,这是一个很好的部分。 不过,它确实带来了一些额外的努力和一些限制,因此您需要考虑这些限制在您的场景中是否可以接受:

  • SharePoint Online 的权限不会像从 SharePoint 用户/组界面内部获得权限的用户那样精细/详细(没有网站/列表/文件夹/项目级别的特定权限等)。在这种方法中,您将授予权限作为设置 Azure AD 应用程序的一部分,并且您只会获得这些通用选项(如下面的屏幕截图所示)

  • Microsoft 在这种情况下有一些有据可查的限制,您可以在此处阅读:What are the limitations when using app-only

因此,总的来说,我建议您选择选项 4 或选项 5,或两者结合用于您的实施,具体取决于您的场景中可接受的限制。

3。使用应用程序设置的代码更改

重要的变化

public static string ServiceSiteUrl = Environment.GetEnvironmentVariable("ServiceSiteUrl");
public static string ServiceUserName = Environment.GetEnvironmentVariable("ServiceUserName");
public static string ServicePassword = Environment.GetEnvironmentVariable("ServicePassword");

工作示例中的完整代码(我用阅读 SharePoint Web 对象的标题和 URL 代替了做某事):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint.Client;
using System.Security;
using System.Security.Principal;

namespace O365SPProject
{
    class Program
    {
        private class Configuration
        {
            public static string ServiceSiteUrl = Environment.GetEnvironmentVariable("ServiceSiteUrl");
            public static string ServiceUserName = Environment.GetEnvironmentVariable("ServiceUserName");
            public static string ServicePassword = Environment.GetEnvironmentVariable("ServicePassword");
        }

        static ClientContext GetonlineContext()
        {
            var securePassword = new SecureString();
            foreach (char c in Configuration.ServicePassword)
            {
                securePassword.AppendChar(c);
            }

            var onlineCredentials = new SharePointOnlineCredentials(Configuration.ServiceUserName, securePassword);
            var context = new ClientContext(Configuration.ServiceSiteUrl);
            context.Credentials = onlineCredentials;
            return context;
        }

        static void Main(string[] args)
        {
            var ClientContext = GetonlineContext();
            ClientContext.Load(ClientContext.Web);
            ClientContext.ExecuteQuery();

            Console.WriteLine("This app found web title as: {0} and URL as: {1}", 
                ClientContext.Web.Title, ClientContext.Web.Url);

            Console.WriteLine("Console app is running with identity {0}", WindowsIdentity.GetCurrent().Name);
        }
    }
}

执行 Azure 函数时的输出

【讨论】:

  • 很高兴您发现它有帮助。祝您实施顺利!
【解决方案2】:

SharePoint REST API 支持 OAuth。这是一个很有前途的article。虽然,这对你的意图来说可能有点多。或者,您可以尝试使用basic auth(用户名+密码)。为了防范纯文本密码,可以将它们存储在 Azure Key Vault 中。

编辑 Azure 函数的当前用户 是 IIS 应用程序池的标识。

【讨论】:

  • 所以回到我的问题,我可以使用哪一点(1,2 或 3)?使用当前的 azure 用户名或使用服务帐户进行 azure 功能或在控制台应用程序本身内部进行身份验证?
  • 我的问题主要是关于控制台应用程序将在哪个帐户下运行,而不是关于 RESP API 功能。现在我可以使用客户端对象模块 CSOM 来进行集成,而不是使用 REST API。我希望这能更好地阐明我的主要问题。谢谢
  • 好的,感谢您的更新。但是我可以修改这个 IIS APP 池用户,使其与我登录的 azure 帐户不同吗?正如我提到的 azure 帐户和在线共享点在不同的租户上,所以我可以使用userA@companyA.com 登录到 azure,然后将 IIS APP Pool 用户定义为Service@comanyB.com 下吗?第二点,同一个azure账号下可以有多个app pool用户吗(类似于on-premises案例)?
  • 我打开了运行我的函数应用的应用服务并将托管标识设置为使用 Azure AD,但该应用仍然在任意用户名下继续运行。我做了一些搜索,发现有人和你有同样的问题(stackoverflow.com/questions/44587136/…)。一位微软软件工程师评论了这篇文章,称它在路线图上。
  • 您的代码看起来可以运行。我将其与工作示例 stackoverflow.com/questions/22313548/… 进行了比较。
猜你喜欢
  • 2022-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-25
  • 2022-08-03
  • 2014-07-01
  • 1970-01-01
  • 2017-07-03
相关资源
最近更新 更多