web-dev-qa-db-fra.com

Comment interroger les rôles de l'utilisateur actuel

Je recherche une instruction select qui récupérera une liste de tous les rôles de base de données pour ma connexion actuelle.

Je veux créer une vue qui retournera tous les rôles à un logiciel client, de sorte que le logiciel puisse ajuster son interface utilisateur en fonction des rôles (par exemple, afficher/masquer les entrées de menu, etc.)

12
SQL Police

Vous ne devez pas utiliser des vues de compatibilité descendante obsolètes ( recherchez cette page pour sysusers, par exemple ). Au lieu de cela, vous devez utiliser sys.database_principals et sys.database_role_members . Gardez à l'esprit que la connexion actuelle peut avoir obtenu un accès en dehors de la portée de la base de données (par exemple, ceux-ci renverront des résultats vides si l'utilisateur se trouve être un sysadmin auquel cas ils n'ont pas besoin d'être explicitement l’appartenance à un rôle ou des autorisations spécifiques). Pour les autorisations attribuées explicitement en dehors de la portée d'un rôle, qui remplaceront celles fournies par le rôle, vous devez également vérifier sys.database_permissions . Voici un exemple autonome que vous pouvez consulter (tant que vous ne disposez pas déjà d'une connexion nommée blatfarA ou d'une base de données appelée floob).

CREATE LOGIN blatfarA WITH PASSWORD = 'foo', CHECK_POLICY = OFF;
GO
CREATE DATABASE floob;
GO
USE floob;
GO
CREATE USER blatfarB FROM LOGIN [blatfarA] WITH DEFAULT_SCHEMA = dbo;
GO
GRANT SELECT, UPDATE ON SCHEMA::dbo TO blatfarB;
DENY INSERT, EXECUTE ON SCHEMA::dbo TO blatfarB;
GO
EXEC sp_addrolemember N'db_datareader', N'blatfarB'
GO

Pour le tester:

EXECUTE AS LOGIN = N'blatfarA';
GO

DECLARE @login NVARCHAR(256), @user NVARCHAR(256);

SELECT @login = login_name FROM sys.dm_exec_sessions WHERE session_id = @@SPID;

SELECT @user = d.name
  FROM sys.database_principals AS d
  INNER JOIN sys.server_principals AS s
  ON d.sid = s.sid
  WHERE s.name = @login;

SELECT u.name, r.name
  FROM sys.database_role_members AS m
  INNER JOIN sys.database_principals AS r
  ON m.role_principal_id = r.principal_id
  INNER JOIN sys.database_principals AS u
  ON u.principal_id = m.member_principal_id
  WHERE u.name = @user;

SELECT class_desc, major_id, permission_name, state_desc
  FROM sys.database_permissions
  WHERE grantee_principal_id = USER_ID(@user);

GO
REVERT;

Résultats:

name      name
--------  -------------
blatfarB  db_datareader

class_desc  major_id  permission_name  state_desc
----------  --------  ---------------  ----------
DATABASE    0         CONNECT          GRANT
SCHEMA      1         INSERT           DENY
SCHEMA      1         EXECUTE          DENY
SCHEMA      1         SELECT           GRANT
SCHEMA      1         UPDATE           GRANT

Nettoyer:

USE master;
GO
ALTER DATABASE floob SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
GO
DROP DATABASE floob;
GO
DROP LOGIN blatfarA;
GO
21
Aaron Bertrand