“创建用户”和“授予连接”在功能上是否相同?

Ben*_*hul 8 sql-server

我本身没有问题,但我注意到如果我向数据库中不存在的主体授予数据库权限,该权限会显示在 sys.database_permissions 中,但用户无法连接到数据库(如预期)。如果我再给grant connect用户,一切都很好。这让我想知道create user和 是否grant connect在功能上是等效的。也就是说,有什么额外的那create user确实是grant connect不?

spa*_*dba 10

您不能向服务器主体授予数据库权限:您需要先创建一个数据库主体,这可能是您已经完成的。

您所指的是缺乏对 GUEST 主体的 CONNECT 特权,这很可能被明智的 DBA 撤销。当 CONNECT 权限未明确授予数据库主体时,它会继承来宾用户的权限。

这是一个重现脚本,可以帮助您了解事情是如何工作的:

-- create a test database
CREATE DATABASE testPermissions;
GO

USE testPermissions;
GO

-- revoke CONNECT permissions from users that 
-- are not granted CONNECT explicitly or
-- do not inherit the permission from server
-- or database roles.
-- this is considered a security best practice
REVOKE CONNECT FROM GUEST;
GO

-- create a test table
CREATE TABLE someTable (
    someColumn int
);
GO

-- insert some values
INSERT INTO someTable VALUES (1);
GO

-- create a login, AKA server principal
-- this login has NO PERMISSIONS on the database
CREATE LOGIN testlogin WITH PASSWORD=N'aVeryLongPasswordNobodyWillEverGuess', CHECK_POLICY = OFF
GO


-- if you try to grant database permissions 
-- to a login you get an error
GRANT SELECT TO testlogin;
GO

-- Msg 15151, Level 16, State 1, Line 1
-- Cannot find the user 'testlogin', because it does not exist or you do not have permission.

-- if you create a database user you are creating
-- a link between a database principal and
-- a server principal with the "FOR LOGIN" clause
CREATE USER testUser FOR LOGIN testLogin;
GO

-- now if you grant some permissions to the 
-- database principal you won't get any errors
GRANT SELECT TO testUser;
GO

-- you can now see that the database principal
-- has been granted some permissions
SELECT pe.class_desc
    ,OBJECT_NAME(pe.major_id) AS target_object_name
    ,pe.permission_name
    ,pr.name AS grantee
    ,pr.type_desc
FROM sys.database_permissions AS pe
LEFT JOIN sys.database_principals AS pr
    ON pe.grantee_principal_id = pr.principal_id
WHERE pr.name = 'testUser';
GO


-- class_desc  target_object_name  permission_name  grantee   type_desc
-- ----------- ------------------- ---------------- --------- ----------
-- DATABASE    NULL                SELECT           testUser  SQL_USER


-- If you try to connect as the "testUser" database principal
-- you will get an error, as it doesn't have CONNECT privileges
EXECUTE AS USER = 'testUser';
GO

-- Msg 916, Level 14, State 1, Line 1
-- The server principal "testlogin" is not able to access the database "testPermissions" under the current security context.

-- Now grant the CONNECT privilege
GRANT CONNECT TO testUser;
GO

-- If you try to connect as testUser things
-- will now work as expected
EXECUTE AS USER = 'testUser';
GO

USE testPermissions
GO

-- the select permissions are already granted:
-- the query works
SELECT *
FROM someTable;

REVERT;
GO
Run Code Online (Sandbox Code Playgroud)