sql >> データベース >  >> RDS >> Sqlserver

SQL Server:スキーマを許可する方法は?

    オーナーシップ チェーンの説明または概念が不明確であると思いますので、それから始めさせてください:

    「所有権の連鎖」とは、SQL Server でストアド プロシージャ (またはビュー) を実行するときに、現在実行中のバッチが、その SQL コードの実行中に sProc の所有者 (または sProc のスキーマの所有者) の権利/権限を一時的に取得するという事実を指します。したがって、sProc の場合、ユーザーはこれらの特権を使用して、sProc コードが実装していないことを行うことはできません。 特に、アイデンティティを取得しないことに注意してください 所有者の、一時的な権限のみです (ただし、EXECUTE AS... はこれを行います)。

    したがって、セキュリティのためにこれを活用する一般的なアプローチは次のとおりです。

    <オール> <リ>

    すべてのデータ テーブル (およびすべての非セキュリティ ビューも同様) を独自のスキーマに入れます。それを [データ] と呼びましょう (ただし、通常は [dbo] が使用されます。これは、既にそこにあり、ユーザーのスキーマに対して特権がありすぎるためです)。既存のユーザー、スキーマ、または所有者がこの [データ] スキーマにアクセスできないことを確認してください。

    <リ>

    すべての sProc (および/または任意のセキュリティ ビュー) に対して [exec] というスキーマを作成します。このスキーマの所有者が [data] スキーマにアクセスできることを確認してください (dbo をこのスキーマの所有者にすれば簡単です)。

    <リ>

    「Users」という名前の新しい db-Role を作成し、[exec] スキーマへの EXECUTE アクセスを付与します。すべてのユーザーをこのロールに追加します。ユーザーが接続権限のみを持ち、[dbo] を含む他のスキーマへのアクセスが許可されていないことを確認してください。

    これで、ユーザーは [exec] で sProcs を実行することによってのみデータにアクセスできるようになります。他のデータにアクセスしたり、他のオブジェクトを実行したりすることはできません。

    これがあなたの質問に答えているかどうかわかりません (質問の正確な内容がわからなかったため)。遠慮なくリダイレ​​クトしてください。

    行レベルのセキュリティに関しては、上記のセキュリティ スキームで常に行う方法を次に示します。

    <オール> <リ>

    私は常に行レベルのセキュリティを一連のビューとして実装し、すべてのテーブルをミラーラップし、ユーザーの ID (通常は Suser_Sname() または他のいずれかを使用) を、行自体のセキュリティ コードをキーにしたセキュリティ リストと比較します。これらはセキュリティ ビューです。

    <リ>

    [rows] という新しいスキーマを作成し、その所有者に [data] スキーマへのアクセス権を付与します。すべての Security-View をこのスキーマに入れます。

    <リ>

    [exec] 所有者の [data] スキーマへのアクセスを取り消し、代わりに [rows] スキーマへのデータ アクセスを許可します。

    終わり。現在、行レベルのセキュリティは、sProcs とテーブルの間で透過的にスリップすることによって実装されています。

    最後に、このあいまいなセキュリティ機能がどの程度機能し、それ自体と相互作用するかを思い出すために使用するストアド プロシージャを次に示します (おっと、コードの修正版 ):

    CREATE proc [TestCnxOnly].[spShowProc_Security_NoEX]  as
    --no "With Execute as Owner" for this version
    --create User [UserNoLogin] without login
    --Grant connect on database :: TestSecurity to Guest
    --alter database TestSecurity set trustworthy on
    
    --Show current user context:
    select current_user as current_
    , session_user as session
    , user_name() as _name
    , suser_name() as [suser (sproc)]
    , suser_sname() as sname
    , system_user as system_
    
    
    --Execute As Login = 'UserNoLogin'
    select current_user as current_
    , session_user as session
    , user_name() as _name
    , suser_name() as [suser (after exec as)]
    , suser_sname() as sname
    , system_user as system_
    
    EXEC('select current_user as current_
    , session_user as session
    , user_name() as _name
    , suser_name() as [suser (in Exec(sql))]
    , suser_sname() as sname
    , system_user as system_')
    
    EXEC sp_ExecuteSQL N'select current_user as current_
    , session_user as session
    , user_name() as _name
    , suser_name() as [suser (in sp_Executesql)]
    , suser_sname() as sname
    , system_user as system_'
    
    --Revert
    select current_user as current_
    , session_user as session
    , user_name() as _name
    , suser_name() as [suser (aftr revert)]
    , suser_sname() as sname
    , system_user as system_
      

    [編集:コードの修正版)



    1. MySQL pythonコネクタ:バイトフォーマット中にすべての引数が変換されるわけではありません

    2. 他の列に基づくSUM(DISTINCT)

    3. チェックボックスの入力に基づいてMySQL列を更新する方法

    4. VARCHARの最大長は4000ですが、保存できるのは2666バイトの長さのタイ語テキストのみです。