2つのウィンドウグループに対応する2つのSQL Serverログインを作成しました。
MachineName\MyAppAmdin
MachineName\MyAppUser
次に、データベースで同じ名前の2人のユーザーを作成し、それらをログインにマップしました。
Windowsサーバーで、ドメインアカウントMyDomain\MyAccount
をMachineName\MyAppAmdin
グループに追加しました。
これで、MyDomain\MyAccount
を介してWindows認証を渡すことができます。
問題は、私が使用しているWindowsグループログインを正確に知りたいのですが、その方法がわかりません。
私は試した:
ORIGINAL_LOGIN()
SYSTEM_USER
SUSER_SNAME
SELECT * FROM dm_exec_sessions
上記はすべてMyDomain\MyAccount
を返しますが、MachineName\MyAppAmdin
のグループメンバーシップを介してログインしていたかどうかを知る必要があります。
要約すると、私の質問は:
現在の接続が使用しているWindowsグループログイン(またはユーザー)を正確に確認する方法はありますか?
または、MyDomain\MyAccount
が特定のユーザーまたはログインに関連付けられているかどうかを確認する方法はありますか?
ドメインアカウントが特定のWindowsグループに属しているかどうかを解決するためにC#またはコマンドを使用できることはわかっていますが、いくつかの新しいITポリシーがあるため、TSQLを使用して同様の結果を達成する方法を考えています。
Windows Authentication
はtoken-based
認証です。tokens
についてはこちら アクセストークン およびこちら トークンベースの認証 をご覧ください。
トークンベースの認証システムの背後にある一般的な概念は単純です。ユーザーがユーザー名とパスワードを使用せずに特定のリソースを取得できるトークンを取得するために、ユーザーがユーザー名とパスワードを入力できるようにします。
アクセストークンは、ユーザーがシステムにログオンし、ユーザーによって提供された資格情報が認証データベースに対して認証されるときに、ログオンサービスによって生成されます。認証データベースには、ユーザーID、プライマリグループID、それが含まれるその他すべてのグループ、その他の情報など、ログオンセッションの初期トークンを作成するために必要な資格情報が含まれています。トークンは、ユーザーセッションで作成された初期プロセスに添付され、初期プロセスによって作成された後続のプロセスによって継承されます。
したがって、Windows Authentication
を使用してログオンすると、Windows token
をサーバーに提示することになります。
次のコードを使用して、login token
の一部であるすべてのサーバープリンシパルを表示できます。
select *
from sys.login_token
--where principal_id > 0; -- uncomment here to see only mapped principals
別のログインのlogin token
を調べたい場合は、最初に偽装する必要があります。
execute as login = 'some_login';
select *
from sys.login_token
where principal_id > 0;
revert;
もちろん、それをIMPERSONATE
できるようにするには、some_login
に対するimpersonate
権限が必要です。
したがって、サーバーでの権限は、トークンの一部となるすべてのプリンシパルの権限の「合計」に基づいて定義されます。 DENY
は常にGRANT
に優先されるため、2人のメンバーである場合はWin groups
のいずれかがgrant
と他のdeny
を持っているオブジェクトへのアクセスは拒否されます。
SQL ServerのWindows認証はそのようには機能しません。ログインが関連付けられているが、ログインが関連付けられているドメイングループからもアクセスできるドメインユーザーとしてログインする場合、アクセスは、両方のユーザーに割り当てられているDENY/GRANT権限とSQL\DBロールメンバーシップによって決定されます。ログインとグループログイン。
グループとして「ログイン」するという概念はありません。グループは、Active Directoryのこのグループのメンバーシップに基づいてドメインユーザーのコレクションへのアクセスを提供するための単なるコンテナーです。
次のコマンドを実行して、特定のユーザーのさまざまなアクセスパスを確認できます。
EXEC xp_logininfo '<DOMAIN\user>', 'all'
これにより、ユーザーのさまざまなアクセスパス、つまり、このWindowsアカウントがリンクされているすべてのグループログインとユーザーログインが一覧表示されます。
HandyDの回答 と sepupicの回答 の両方に良い情報がありますが、それでもいくつかの説明が必要です。
Windows認証を使用してログインすると、セキュリティコンテキストには、現在のWindowsセキュリティコンテキストに一致するsys.server_principals
にマップされたログインのallが含まれます。これは、Windowsログインまたは1つ以上のWindowsグループにすることができます。 Windowsアカウントが5つのグループにあり、そのうちの3つのグループがSQL Serverのログインとして登録されているが、特にログインがない場合、セキュリティコンテキストはこれらの3つのグループだけになります。次に、特にWindowsアカウントのログインを追加した場合、ログインすると、Windowsログインのセキュリティコンテキストに加えて、マッピングされた3つのグループすべてが提供されます。
xp_logininfo は、アカウントとしてログインしたり、偽装したりすることなく、一致するマッピングされたグループやアカウントのログインを表示できるので便利です。また、Windowsグループのメンバーを表示できます(WindowsグループがSQL Serverにログインとして登録されている場合)。
このシステムストアドプロシージャで表示できないものは次のとおりです。
xp_logininfo
は、包含データベースの内部でのみ機能するため、包含DBについては何も表示しませんifインスタンスレベルの照合がLatin1_General_100_CI_AS_KS_WS_SC
テスト中に発見したバグが原因: xp_logininfoは、「メッセージ468、レベル16、状態9:照合の競合を解決できません...」と、DB照合がインスタンスの照合と一致しない場合に発生します。 )sys.login_token は、fullセキュリティコンテキスト(Windowsログイン(マップされている場合)やWindowsグループ(いずれかがマップされます)、およびログインやグループがメンバーであるサーバーレベルのロール。 「有効な」権限は、すべてのセキュリティトークンにわたるすべての権限に基づいており、DENY
はすべてのGRANT
sをオーバーライドします。したがって、グループ1のメンバーシップを介して何かへのアクセス許可を付与できますが、グループ2はそのアクセス許可(または親のアクセス許可)を拒否されたサーバーレベルの役割のメンバーであるため、そのアクセス許可は事実上拒否されます。
このDMVで表示できないものは次のとおりです。
sys.user_token は、データベースレベルでfullセキュリティコンテキストを確認するのに役立ちます。セキュリティトークンはデータベースごとに異なる可能性があるため、このDMVがチェックされるとき、有効な権限は常に現在のデータベースに基づいています。このDMVは、Contained DBに直接ログインする場合のより関連性の高い情報です。
これは、使用されているユーザーを見つけるために通常使用するものです。
ただし、ユーザーがデータベースへのアクセスを許可されている現在のWindowsグループを返します。
-- get the current login name
-- marcelo miorelli
-- 26-11-2013
DECLARE @User VARCHAR(20)
SELECT @USER = SUBSTRING(SUSER_SNAME(), CHARINDEX('\', SUSER_SNAME()) + 1, LEN(SUSER_SNAME()))
SELECT [THE_SERVER]= @@SERVERNAME
,[DB_NAME] =DB_NAME()
,[@USER]=@USER
,[SUSER_SNAME()]=SUSER_SNAME()
,[SYSTEM_USER]=SYSTEM_USER
,[USER_NAME()]=USER_NAME()
,[CURRENT_USER]=CURRENT_USER
,[ORIGINAL_LOGIN()]=ORIGINAL_LOGIN()
,[USER]=USER
,[SESSION_USER]=SESSION_USER
上記をテストするため、またはいくつかの許可または手順をテストするために、以下の例のようなものを実行します。
-- to check how a specific procedure will run under a different account
EXECUTE AS LOGIN='mycompany\Celcatsupport'
-- checking who I am running the commands as (impersonating)
DECLARE @User VARCHAR(20)
SELECT @USER = SUBSTRING(SUSER_SNAME(), CHARINDEX('\', SUSER_SNAME()) + 1, LEN(SUSER_SNAME()))
SELECT [THE_SERVER]= @@SERVERNAME
,[DB_NAME] =DB_NAME()
,[@USER]=@USER
,[SUSER_SNAME()]=SUSER_SNAME()
,[SYSTEM_USER]=SYSTEM_USER
,[USER_NAME()]=USER_NAME()
,[CURRENT_USER]=CURRENT_USER
,[ORIGINAL_LOGIN()]=ORIGINAL_LOGIN()
,[USER]=USER
,[SESSION_USER]=SESSION_USER
--reverting back to my original login
REVERT
次のスクリプトは、現在のログインに使用されたグループを提供しませんが、多くの場面で私にとって非常に役立ちました
--the following query will give you
--all the available windows group that
--have login in the current server
--and @NTLogin belongs to
declare @NTLogin nvarchar(128)
select @NTLogin = 'mycompany\myuser'
DECLARE @UserList TABLE (
[Account Name] nvarchar(128)collate Latin1_General_CI_AS,
[Type] nvarchar(128) collate Latin1_General_CI_AS,
[Privilege] nvarchar(128) collate Latin1_General_CI_AS,
[Mapped Login Name] nvarchar(128)collate Latin1_General_CI_AS,
[Permission Path] nvarchar(128) )
INSERT INTO @UserList EXEC master.dbo.xp_logininfo @NTLogin, 'all' --insert group information
IF EXISTS (SELECT * FROM @UserList WHERE [Type] = 'group') --only if it's a group
INSERT INTO @UserList EXEC master.dbo.xp_logininfo @NTLogin, 'members' --insert member information
SELECT [Server Name] = @@SERVERNAME,
[Account Name],
[Type],
[Privilege],
[Mapped Login Name],
[Permission Path]
FROM @UserList
IS_MEMBER()
が、現在のユーザーが、作成したWindowsグループのメンバーであるかどうかを確認できることがわかりました。