要求:
我有一个SSIS项目,它将运行SQL Server中的数据,可能使用集成身份验证登录到SQL Server。
该项目包括一个部分,允许最终用户将选择查询添加为一个数据流的源。 (该产品允许用户在配置文件中添加数据分类和过滤类型规则)
我希望用户提供的这些查询在具有只读访问权限的受限上下文中运行。通过在查询中添加DELETE
或DROP
,某人无法删除数据库。
首过解决方案:
在数据库上创建只读用户,并使用EXECUTE AS ... WITH NO REVERT
将查询的上下文限制为只读用户。不幸的是,这并不完全有效。 SSIS在数据源组件中使用预准备语句,SQL Server在准备好的语句中不允许WITH NO REVERT
。
问题:
有没有办法强制SSIS使用ad-hoc查询代替OLEDB数据源组件中的预处理语句?
或者......是否有其他方法可以强制SSIS更改数据源组件的执行上下文?
我还有另外一个解决方案:使用脚本组件源。脚本组件可以通过多种方式设置用户上下文。
答案 0 :(得分:1)
stackoverflow上有一些答案建议将它包装在BEGIN TRAN / ROLLBACK TRAN中。这可以在单独的SQL任务中,删除使用偷偷摸摸注入禁用它们的功能。但他们仍然可以将DROP DATABASE注入您的数据流。无法回滚那个。
您是否检查过DML是否在数据流源中运行?
我确实质疑这个架构......在SSIS中运行用户定义的查询?
答案 1 :(得分:0)
您可以使用ad-hoc
选项在OLEDB source
中使用SQL Command from Variable
查询。您可以创建变量并键入sql查询并在OLEDB源组件中使用它。使用XML配置并将变量添加到它。如果您在query
期间更改将在SSIS中反映的XML中的runtime
。然而,SSIS严重依赖于Metadata
。即使在执行之前,SSIS也会验证元数据。如果您在XML中更改查询(例如更改列名),则SSIS将发现元数据不匹配,包将{{1 }}
答案 2 :(得分:0)
我为此确定的最终解决方案是使用脚本源组件将用户提供的SELECT
与EXECUTE AS user WITH NO REVERT
包装起来。我确信使用权限结构来防止未经过操作的操作比使用事务更好。
我创建了两个连接管理器。一个(称为connection_RO)是一个ADO.NET连接管理器,只有执行用户提供的查询的组件才会使用它。另一个(connection_RW)用于其他一切,包括转换用户提供的查询中的数据并将其写回。
有一个脚本源组件执行用户提供的查询。它使用EXECUTE AS ...子句为查询添加前缀,以将用户锁定在只读上下文中。
要解决的下一个问题是默认情况下所有连接都是池化的,当您选择以前在池中使用的连接时,框架会发送sp_reset_connection
。抛出异常是因为SQL Server将其视为尝试升级权限。因此,connection_RO连接管理器必须配置为没有池。
最终结果是我可以放心地运行用户提供的查询,用户不会恶意或意外地造成任何损害。