在哪个帐户下运行Azure Function应用程序中承载的.net控制台应用程序

时间:2018-09-10 23:09:10

标签: azure sharepoint office365 azure-functions

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

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

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

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

OR

  • 我可以为要在其下运行的Azure功能应用程序定义一个服务帐户,在这种情况下,我可以将该服务帐户定义为在线sharepoint内部的授权帐户?

OR

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

那么任何人都可以对此提出建议吗? 谢谢

编辑

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

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            

        } 

    } 

}

2 个答案:

答案 0 :(得分:5)

您的问题有多个部分,因此我将相应回答。

1。您应该使用哪三个选项来管理配置数据/服务帐户标识

(或者,如果有其他更好的选择:)

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

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

  

我可以为Azure功能应用程序定义一个服务帐户以在以下位置运行   它,在这种情况下,我可以将服务帐户定义为   共享点内部有授权帐户?

但是区别在于,我并不是说您将能够为要在其下运行的Azure功能应用程序定义一个服务帐户(因为您无法控制将要在其下运行Azure功能的帐户,因此Microsoft基础结构会负责它),而是将其作为安全配置数据传递到控制台应用程序,然后控制台应用程序将使用它。比较选项时,稍后会详细介绍安全性/加密。

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

添加应用程序设置-导航您的Azure Function应用程序,然后单击“应用程序设置”

enter image description here

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

enter image description here

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

选项5 在Azure AD中注册一个新的应用程序以代表您的Azure功能。

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

这里是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

enter image description here

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

选项5-此选项利用基于Azure AD的身份向SharePoint Online进行身份验证,这是很好的一部分。 它确实需要付出额外的努力和一些限制,因此您需要考虑这些限制在您的情况下是否可以接受:

  • SharePoint Online的权限不会像从SharePoint Users / Groups界面内部获得权限的用户那样细化/详细(没有网站/列表/文件夹/项目级别的特定权限等)。通过这种方法,您将在设置Azure AD应用程序的过程中授予权限,并且只会获得此类通用选项(如下面的屏幕快照所示)。 enter image description here

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

因此,总的来说,我建议您选择方案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 Function时的输出 enter image description here

答案 1 :(得分:3)

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

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

Code Logs

相关问题