SE の雑記

SQL Server の情報をメインに Microsoft 製品の勉強内容を日々投稿

SQL Server のログイン / ユーザーの権限を SSMS を使用しながら確認してみる

leave a comment

SQL Server の権限設定ですが、基本的な考え方は プリンシパル (データベース エンジン) に記載されている内容となります。

権限としては、次の二種類に分けられます。

  • ログイン : インスタンスレベルでの操作権限
  • ユーザー : データベースレベルでの操作権限

「ログイン」と「ユーザー」という複数のプリンシパルに分かれているため、理解しづらい構成になっているのですが、SSMS を使用しながらであればわかりやすいかなと思いましたので軽くまとめてみようかと。

今回使用するログインですが、次のクエリで作成したものを使用しています。

CREATE LOGIN tpch WITH PASSWORD='tpch', CHECK_POLICY=OFF

 
「sysadmin」固定サーバーロールや「db_owner」固定データベースロールがついてしまっていると、状況が変わってくるので、「初期実行の権限を明示的に使用していないログイン」を基点としています。
SQL Server で設定可能な権限ですが、次のドキュメントを調べるのが基本となります。

これらの操作を行いながら、適切な権限の付与を行っていきます。
権限は階層構造になっているのですが、細かな内容については https://aka.ms/sql-permissions-poster で確認することができます。
 

ログインの権限を確認する

このログインを使用して、SSMS で接続を行ってみます。

SSMS で接続を実施すると、正常に接続することができるはずです。
image
「作成した直後のログインが接続できた」のはなぜでしょうか?
それでは、「ログイン」にどのような権限が付与されているのかを見てみましょう。

ログインの権限については、次のようなクエリで確認することができます。

SELECT
	spr.name,
	spe.class_desc,
	spe.type,
	spe.permission_name,
	spe.state,
	spe.state_desc
FROM
	sys.server_principals spr
	left join
	sys.server_permissions spe
ON
	principal_id = grantee_principal_id
WHERE
	name in('tpch')

 
image
「CONNECT SQL」が許可されていますので、「SQL Server に接続する権限」は付与されていることが確認できました。
「CREATE USER」により作成したユーザーは「CONNECT SQL」の権限がデフォルトで付与されており、「SQL Server のインスタンスに接続するための権限」を持った状態となっているため接続を行うことができました。
SSMS で接続を行うと、データベースの下には作成済みのデータベースが存在していることが確認できます。
「ログイン : tpch」には、「CONNECT SQL」しか権限が付与されていないのですが、なぜデータベースの一覧が表示されているのでしょうか?
「SQL Server で作成した全てのログイン」は 「public」という固定サーバーロールのメンバーとなります。
 
それでは、先ほど実行したクエリを次のように書き換えてみましょう。

SELECT
	spr.name,
	spe.class_desc,
	spe.type,
	spe.major_id,
	spe.permission_name,
	spe.state,
	spe.state_desc
FROM
	sys.server_principals spr
	left join
	sys.server_permissions spe
ON
	principal_id = grantee_principal_id
WHERE
	name in('tpch', 'public')

取得結果がこちらになります。
image
「public」に対して「SERVER」レベルの「VIEW ANY DATABASE」が付与されていることが確認できますね。

これにより、「どのようなデータベースが存在しているか」を確認する権限が付与されていることになります。
それでは、次のクエリで「public」から権限を取り消してみるとどうでしょう。

REVOKE VIEW ANY DATABASE TO public

権限の取り消しを行い、SSMS の表示を最新にすると「データベースの一覧」が表示されなくなりました。
image
このように「ログインの権限」は「自ログインの権限」+「public の権限」の二つにより制御が行われています。
まずは、これでログインの権限を確認することができましたので、次は「ユーザー」の権限を見ていきましょう。

ユーザーの権限を確認する

今回の環境では「tpch」というデータベースがすでに作成されています。
それでは先ほどまで、使用していた「ログイン : tpch」でこのデータベースにアクセスしようとするとどうなるでしょうか。
現在の状態では、次のようなエラーが発生します。
image
「ログイン : tpch」は「SQL Server に接続をし、DB の一覧を表示する権限」は持っていることになります。
しかし「データベース : tpch にアクセスする権限」は付与していません。
データベースにアクセスるためには、「アクセス対象のデータベースに「ユーザー」を作成し、適切な権限を付与する」必要があります。

(この辺が SQL Server の権限周りで分かりづらい場所ではあるのですが)
ユーザーは次のクエリで作成することができます。

USE [tpch]
GO
CREATE USER [tpch] FOR LOGIN [tpch]
GO

 
これでデータベースに接続することができました。
image
現状、テーブルには何も表示されていない状態ですね。

何もテーブルが作成されていない状態なのかと言うと、そういうことではありません。
image
「sysadmin」固定サーバーロールのログインで接続した場合はテーブルの表示が行われています。
「ユーザーによって表示されている内容が異なっている状態」になっていますね。
それでは「ユーザー」にどのような権限が付与されているか見てみましょう。

SELECT
	dpr.name,
	spe.class_desc,
	spe.type,
	spe.major_id,
	CASE spe.type
	WHEN 'EX' THEN (SELECT name From sys.all_objects WHERE object_id = major_id)
	WHEN 'SL' THEN (SELECT name From sys.all_objects WHERE object_id = major_id)
	ELSE CAST(major_id AS sysname)
	END AS object_info,
	spe.permission_name,
	spe.state,
	spe.state_desc
FROM
	sys.database_principals dpr
	left join
	sys.database_permissions spe
ON
	principal_id = grantee_principal_id
WHERE
	name in('tpch', 'public')
ORDER BY
	name ASC

 
「public」には、いくつかの権限が付与されているのですが、「tpch」には、特に権限の付与は行われていない状態です。
image
今回、既定のスキーマは「dbo」なのですが、「dbo」というスキーマに対してはなにも権限が付与されていない状態となっています。
それではデータベースの権限について考えてみましょう。

データベースの権限は次のようになっています。

この権限の一覧の中で、ログインについていた「VIEW ANY DATABASE」の権限を確認しても、それにより付与されている「データベース権限」は存在していません。
つまに、「VIEW ANY DATABASE」の権限を付与したとしても、データベースに対しての権限が付与されていない状態となります。
それでは「データベースにどのようなオブジェクトが含まれているか?」についてはどのように考えればよいでしょうか。

この情報を確認すると次のような表があります。
image
定義を確認するためには「VIEW DEFINITION」という権限があればよさそうですね。

USE [tpch]
GO
GRANT VIEW DEFINITION TO tpch

 
付与した結果がこちらになります。
定義を参照するための権限を付与しましたので、テーブルが表示されるようになりました。
image
これは「定義を表示するための権限」ですので、「SELECT」を使用としても次のようなエラーとなります。

image
それでは、SELECT を行うためにはどのような権限が必要となるのでしょうか?

ドキュメントを確認してみます。

大抵のステートメントには、「アクセス許可」という項目があります。

これが、ユーザー (またはログイン) が必要となる権限です。
image
今回の場合は「SELECT 権限」が必要ということが確認できますね。

SELECT はオブジェクトに対して実行しますので、次のドキュメントを確認します。

 
SQL Server のテーブルは「スキーマの中にテーブルが含まれる」という階層構造になっていますので、「オブジェクト単体」または「スキーマ全体」に対して権限を付与することでアクセスを許可することができます。
image
先ほどの customer というテーブルは「dbo」のスキーマ配下ですので次のようないずれかの権限付与でアクセスを許可することができます。

(SELECT を付けることで、定義も見えるようになり、VIEW DEFINITION を取り消しても定義は見えた状態になるかと)

USE [tpch]
GO
GRANT SELECT ON OBJECT::dbo.customer TO tpch
または、
USE [tpch]
GO
GRANT SELECT ON SCHEMA::dbo TO tpch

 
これで、「ログイン」「ユーザー」に対しての権限の基本的な設定は終わりです。

あとは、必要となる操作に対して個別に権限の付与を実施したり、「ロール」という形で事前定義を行い再利用できる形で定義を行いながらセキュリティの設定を行います。
古めのドキュメントとなるのですが、SQL Server Best Practices ? Implementation of Database Object Schemas に権限の設定例を交えながら、セキュリティの設定の一例が記載されていますので、一度こちらを確認してみても良いのではないでしょうか。

Share

Written by Masayuki.Ozawa

4月 23rd, 2019 at 11:34 pm

Posted in SQL Server

Tagged with

Leave a Reply