【问题标题】:Prevent dropping of users when publishing a DACPAC using SqlPackage.exe使用 SqlPackage.exe 发布 DACPAC 时防止删除用户
【发布时间】:2013-07-01 11:01:39
【问题描述】:

在使用 SqlPackage.exe 发布 DACPAC 时,有什么方法可以防止用户被删除,除了更改下面的设置,这样可以防止所有不在 DACPAC 中的对象被删除。

<DropObjectsNotInSource>True</DropObjectsNotInSource>

我们部署到多个环境,每个环境都有不同的用户。当前的解决方法是:

  1. 为每个环境编写用户脚本,以便在部署后重新创建它们
  2. 使用/Action:Script 并手动更改部署脚本。

这些都不是理想的...

【问题讨论】:

    标签: sql-server-data-tools


    【解决方案1】:

    使用 SqlPackage.exe 参数(自 2015 年 2 月发布:New Advanced Publish Options to Specify Object Types to Exclude or Not Drop):

    这是我们在部署中使用的实际参数:

    /p:DropObjectsNotInSource=True 
    /p:ExcludeObjectTypes=Users;Logins;RoleMembership;Permissions
    

    第一行清除了所有内容,但下一行进一步细化了不要丢弃的内容。事实证明,这种组合对我们来说是最有效的,可以删除所有不必要的对象,同时保留登录映射。

    所有参数及其可能值的详细文档可以从MSDN - SqlPackage.exe找到

    【讨论】:

    • 可能还需要排除:Credentials;DatabaseScopedCredentials
    • 我认为基于在项目文件中进行这些更改(实际上它被保存到 .sqlproj.user 文件中),它会被编译到 dacpac 中。不是这样吗?唯一的方法是作为SqlPackage.exe 参数传递?
    • 不知道,我不知道你可以使用发布配置文件而不是参数。
    • 请注意,如果您在 powershell 中运行,则对象类型列表需要用引号引起来:/p:ExcludeObjectTypes="Users;Logins;RoleMembership;Permissions"
    【解决方案2】:

    我遇到了同样的问题,并使用 Pre/Post 部署脚本重新插入用户、权限、角色等,就像建议的博客文章一样。但是,从长远来看,这变得无法维护(用户在部署期间无法进行身份验证,如果部署失败权限不会恢复,安全更改需要通过源代码控制和重新部署)。

    最近,我在迁移部署平台时重新评估了这个问题。随着DacFx API(和bug fixes)的发布,我能够通过创建一个DeploymentPlanModifier 来扩展SSDT 中的部署过程。他们提供了一个example for filtering objects on creation,通过简单的修改,我过滤了基于权限的对象类型的任何丢弃(使用/p:AdditionalDeploymentContributors 参数)。

    [ExportDeploymentPlanModifier( UserMappingFilter.PlanFiltererContributorId, "1.0.0.0" )]
    public class UserMappingFilter : DeploymentPlanModifier
    {
        public const string PlanFiltererContributorId = "Dac.UserMappingFilter";
    
        protected override void OnExecute( DeploymentPlanContributorContext context )
        {
            DeploymentStep next = context.PlanHandle.Head;
            while( next != null )
            {
                DeploymentStep current = next;
                next = current.Next;
    
                DropElementStep dropStep = current as DropElementStep;
                if( dropStep != null && ShouldFilter( dropStep ) )
                {
                    base.Remove( context.PlanHandle, dropStep );
                }
            }
        }
    
        private bool ShouldFilter( DropElementStep createStep )
        {
            TSqlObject target = createStep.TargetElement;
    
    
            if( target.ObjectType.Name == "RoleMembership" || target.ObjectType.Name == "User" || target.ObjectType.Name == "Role" )
            {
                return true;
            }
    
    
            return false;
        }
    }
    

    【讨论】:

    • 你能解释一下怎么做吗?我找不到如何安装/设置/无论如何。我发现了一些我需要创建 dll 以将其作为 /p:AdditionalDeploymentContributors 参数传递的东西,但是我找不到如何创建这个 dll
    • 嘿 sidux - 您可以使用为您预先制作的这个,也可以将其用作编写自己的基础:agilesqlclub.codeplex.com(我写的)-更多详细信息the.agilesql.club/Blogs/Ed-Elliott/…
    • 如何使用自己的?我正在与 Ed(agilesqlclub 的作者)沟通,但我们还不能让它工作。我正在使用 VS2012 SSDT。主要问题是我不知道 VS2012 使用的 SqlPackage.exe 位于何处。我尝试了搜索,还有很多其他的东西,但仍然没有效果
    【解决方案3】:

    我们在部署后脚本中处理这个问题。设置起来有点困难,但是一旦设置好,您就可以为每个环境配置稍微不同的脚本。我们将此与发布配置文件结合使用,每个环境具有不同的配置文件。基本上,您使用 Powershell 为用户和权限生成一堆脚本,将这些脚本添加到您的项目中,然后将文件包含在项目中。将博客文章中称为“SecurityAdditionsWrapper.sql”的内容添加到您的部署后脚本中,您应该会很好。只需从您的项目中删除其他安全性以确保其设置正确。

    http://schottsql.blogspot.com/2013/05/ssdt-setting-different-permissions-per.html

    SSDT 中还有以下选项: “删除不在源中的权限” - 错误 “删除源中未定义的角色成员” - 错误 “忽略权限” - 真 “忽略角色成员资格” - True

    我们使用这些,但如果您需要通过环境更好地控制您的用户/权限,我强烈建议您查看该博客文章。 (感谢 Jamie Thomson 的最初想法。)

    【讨论】:

    猜你喜欢
    • 2014-06-16
    • 2021-01-20
    • 2016-02-07
    • 1970-01-01
    • 2015-09-11
    • 1970-01-01
    • 1970-01-01
    • 2017-01-19
    • 2018-09-18
    相关资源
    最近更新 更多