複数のデータベースでls_readonly
権限を持っているはずのユーザーdb_datareader
を持っています。私はそれを正しく設定したと思いました:
しかし、ls_readonly
としてサーバーに接続し、オブジェクトエクスプローラーでデータベースを開こうとすると、エラーが発生します。
データベースwtestにアクセスできません。 (ObjectExplorer)
master
でクエリウィンドウを開き、実行してみます。
use wtest
これは次のように応答します:
Msg 916, Level 14, State 1, Line 1
The server principal "ls_readonly" is not able to access the database "wtest" under the current security context.
何が欠けていますか?
UPDATE:ここに手がかりがあります。データベースのセキュリティコンテキストの下からユーザーとしてls_readonly
を削除すると、サーバーのセキュリティコンテキストの下のユーザーに移動し、[ユーザーマッピング]でデータベースへのアクセスを許可すると、データベースが機能し始めます。
データベースは元々、ls_readonly
ユーザーがいる別のサーバーから復元された可能性があります。ユーザー識別はユーザー名に基づいていないと思いますか?
データベースは元々、ls_readonlyユーザーを持つ別のサーバーから復元された可能性があります。ユーザー識別はユーザー名に基づいていないと思いますか?
通常、すべてのログインは、対応するユーザーと同じsid
を持っています。これがCREATE USER FROM LOGIN
コマンドの意味です。データベースプリンシパルは、対応するログインと同じsid
(セキュリティ識別子)で作成されます。
このユーザーsid
はデータベースに保存され、データベースをbackup
/restore
すると、sidも保持されます。
2つのサーバーがあり、両方にls_readonly
ログインしているとします。簡単にするために、最初のサーバーではls_readonly
はsid
= 1、2番目のサーバーではsid
= 2です。このログインがマップされているデータベースMyDBがあります。最初のサーバーでは、MyDBはsid
= 1を格納し、2番目のサーバーではsid
= 2を格納します。
最初のサーバーでMyDBデータベースをバックアップし、2番目のサーバーで復元します。これで、ログインはsid
= 2になり、データベースMyDBではsid
= 1になります。
ls_readonly
としてログインし、MyDBにアクセスしようとすると、サーバーはデータベースにsid = 2があるかどうかを確認しています。存在しないため、サーバーls_readonly
はMyDBにまったくマップされていません。
これは次のようにして修正できます
alter user ls_readonly with login = ls_readonly;
このコマンドは、ls_readonly
ユーザーのデータベースのsidをls_readonly
ログインのsidで更新するだけです。すべての権限が保持されます。
ユーザーを削除して再作成した場合、ユーザーを削除すると、そのユーザーに付与されているすべての権限が削除されるため、それらを再度付与する必要があります。
@sepupicは非常にうまく提案したすべてのものをカバーしていますが、あるSQL Serverインスタンスからバックアップされ、別のインスタンスに復元されたデータベースを復元するときに実行する次のスクリプトを共有すると思いました。復元したデータベースで実行します。基本的に、@ sepupicが話していることを自動化します。 (execute
はコメント化されています)
SET NOCOUNT ON
DECLARE @cmd nVARCHAR(max) = ''
SELECT @Cmd = @cmd + 'ALTER USER ' + dp.NAME + ' WITH LOGIN = ' + dp.NAME + ';' + CHAR(10)
FROM sys.database_principals dp
LEFT JOIN master.sys.server_principals sp ON sp.NAME = dp.NAME
WHERE dp.type = 's'
AND dp.default_schema_name <> dp.NAME
AND sp.NAME IS NOT NULL
ORDER BY dp.NAME
PRINT @Cmd
--EXECUTE sp_executeSQL @CMD
これは孤立したユーザーのように聞こえます。孤立したユーザーとは、ユーザーSIDがログインSIDと一致しない場所であり、わかりやすい名前ではありません(ログインがサーバーから削除されたか、データベースが別のサーバーから復元されたことが原因である可能性があります)。既存のすべての権限が失われるため、ユーザーを削除して再作成する必要はありません(これは単なる役割ですが、他のオブジェクトに対する個別の権限(ストアドプロシージャやテーブルなど)があると言います)。 (同じ名前であっても)ユーザーをログインに再マッピングできる機能があります。
use db1
GO
alter user [user_name] with login = [login_name]
だからそれはしたいです:
use wtest
GO
alter user [ls_readonly] with login = [ls_readonly]
MSドキュメントの詳細については こちら を参照してください