[英]C# clr udf for Active Directory group membership
My problem is as follows: I need a clr udf (in C#) to query with a given ad-usr the ad-group membership 我的问题如下:我需要一个clr udf(在C#中)与给定的ad-usr查询广告组成员资格
using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.DirectoryServices.AccountManagement;
public partial class UserDefinedFunctions
{
[Microsoft.SqlServer.Server.SqlFunction]
public static SqlInt32 check_user_is_part_of_ad_grp(SqlString ad_usr, SqlString ad_grp)
{
bool bMemberOf = false;
// set up domain context
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
// find the group in question
GroupPrincipal group = GroupPrincipal.FindByIdentity(ctx, ad_grp.ToString());
UserPrincipal usr = UserPrincipal.FindByIdentity(ctx, ad_usr.ToString());
if (group != null && usr != null)
{
bMemberOf = usr.IsMemberOf(group);
}
// Put your code here
return new SqlInt32 (bMemberOf ? 1 : 0);
}
}
If I publish the CLR to my SQL Server 2008 (.net 3.5), then I run the udf as follows: 如果我将CLR发布到我的SQL Server 2008(.net 3.5),那么我按如下方式运行udf:
select dbo.check_user_is_part_of_ad_grp('user', 'group')
And I get an error: 我收到一个错误:
Msg 6522, Level 16, State 1, Line 1
Msg 6522,Level 16,State 1,Line 1
A .NET Framework error occurred during execution of user-defined routine or aggregate "check_user_is_part_of_ad_grp":执行用户定义的例程或聚合“check_user_is_part_of_ad_grp”期间发生.NET Framework错误:
System.Security.SecurityException: Request for the permission of type 'System.DirectoryServices.DirectoryServicesPermission, System.DirectoryServices, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' failed.System.Security.SecurityException:对类型'System.DirectoryServices.DirectoryServicesPermission,System.DirectoryServices,Version = 2.0.0.0,Culture = neutral,PublicKeyToken = b03f5f7f11d50a3a'的权限的请求失败。
System.Security.SecurityException:System.Security.SecurityException:
at UserDefinedFunctions.check_user_is_part_of_ad_grp(SqlString ad_usr, SqlString ad_grp)在UserDefinedFunctions.check_user_is_part_of_ad_grp(SqlString ad_usr,SqlString ad_grp)
I set the target framework of my project to 3.5 and the permission level to EXTERNAL_ACCESS
. 我将项目的目标框架设置为3.5,将权限级别设置为
EXTERNAL_ACCESS
。 Also the project references ( System.DirectoryServices
, System.DirectoryServices.AccountManamgement
, System.DirectoryServices.Protocols
) to EXTERNAL
项目引用(
System.DirectoryServices
, System.DirectoryServices.AccountManamgement
, System.DirectoryServices.Protocols
)到EXTERNAL
I appreciate any help 我感谢任何帮助
Most likely all of those Assemblies will need to be set to UNSAFE
, especially the three System.DirectoryServices* .NET Framework libraries that you imported. 很可能所有这些程序集都需要设置为
UNSAFE
,尤其是您导入的三个System.DirectoryServices * .NET Framework库。 Also, since you are importing unsupported .NET Framework libraries , you will need to set the database to TRUSTWORTHY ON
in order to get them to work. 此外,由于您要导入不受支持的.NET Framework库 ,因此您需要将数据库设置为
TRUSTWORTHY ON
才能使它们正常工作。 Setting a Database to TRUSTWORTHY ON
is typically something you want to avoid as it is a security risk, but in this case I do not believe that it can be avoided. 将数据库设置为
TRUSTWORTHY ON
通常是您要避免的,因为它存在安全风险,但在这种情况下,我不相信它可以避免。
That said, I am not sure that you even need to create this function yourself in SQLCLR. 也就是说,我不确定您是否需要在SQLCLR中自己创建此功能。 If you are just wanting to know if a Login (Windows Logins only, obviously) belongs to a particular Active Directory group, there is a built-in function that should do that for you.
如果你只是想知道,如果一个登录(Windows登录唯一的,很明显)属于特定的Active Directory组,有一个内置的功能应该为你做的。 The IS_MEMBER function will indicate if the current Login is a member of the specified Windows group (specified as
Domain\\Group
). IS_MEMBER函数将指示当前 Login是否是指定Windows组(指定为
Domain\\Group
)的成员。 The difference in how this function works as opposed to the one that you are creating is that it only works for the current Login; 与您正在创建的函数相比,此函数的工作方式不同之处在于它仅适用于当前的Login; you cannot pass any arbitrary Login into it.
你无法通过任意登录。 BUT, it also doesn't require any of the extra effort and security risks that are a part of this SQLCLR solution.
但是,这也并不需要任何的是这个 SQLCLR解决方案的一部分额外的努力和安全风险。 So, something to consider :-).
所以,需要考虑的事情:-)。
Comment from OP on this answer: OP对此答案的评论:
Actually, I need to check an arbitrary Login if it's member of a particular group.
实际上,如果它是特定组的成员,我需要检查任意登录。 I even tried to use a stored proc and `OPENQUERY' with a linked server to ADSI, but this only works as Dynamic SQL since I need to inject group and user.
我甚至尝试将存储过程和“OPENQUERY”与链接服务器一起用于ADSI,但这只能用作动态SQL,因为我需要注入组和用户。
In that case, just make the Dynamic SQL two layers deep instead of the usual one layer. 在这种情况下,只需将动态SQL两层深层而不是通常的一层。 Something along the lines of:
有点像:
DECLARE @SQL NVARCHAR(MAX);
SET @SQL = N'
SELECT *
FROM OPENQUERY([LinkedServer], N''
SELECT *
FROM someResource
WHERE GroupName=N''''' + @Group + N'''''
AND ObjectName=N''''' + @Login + N''''';
'');
';
PRINT @SQL; -- DEBUG
EXEC (@SQL);
In this approach, the query executing OPENQUERY
is Dynamic SQL, but the query given to OPENQUERY
to execute is a string literal. 在此方法中,执行
OPENQUERY
的查询是动态SQL,但是给OPENQUERY
执行的查询是字符串文字。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.