2017-07-13 5 views
7

Guten Tag, ohne zu versuchen,C#: Überprüfen, ob Benutzer den Zugriff auf Server Hat Verbindung

Ich bin derzeit ein Problem konfrontiert, wo ich eine Liste von Servernamen haben, und ich brauche, um zu überprüfen, dass ein Windows-authentifizierten Benutzer hat Berechtigungen die angegebenen Servernamen, ohne zu versuchen, eine Verbindung zum angegebenen Server herzustellen, bevor ich ihnen die Liste der Server vorstelle. So zum Beispiel:

Server: A, B, C, D

Joe hat Berechtigungen A und D, aber nicht B und C so Joe sollte nur A und D in seiner Serverliste.

Wie soll ich dieses Problem angehen? Soll ich aus Active Directory ziehen? Ich weiß, wie ich die Identität meines Benutzers ermitteln kann, aber wo die Serverinformationen abgerufen werden und ob ein Benutzer Berechtigungen hat, ist eine völlig andere Geschichte. Jede Dokumentation, Codebeispiele, Artikel usw. sind hilfreich.

Hinweise über die Arbeitsumgebung

  1. alle Server in der Liste sind Datenbankserver SQL Server 2008 R2 und höher.
  2. Dies ist eine Regierungsumgebung, in der es starke Einschränkungen gibt.
  3. Ich kann Active Directory in keiner Weise ändern.
  4. Ich kann Active Directory und SQL Server den ganzen Tag abfragen, vorausgesetzt der Benutzer verfügt über Berechtigungen.
  5. Die Verwendung von Bibliotheken und Tools von Drittanbietern ist nicht gestattet.

Side Hinweis über die Serverliste

Diese Liste in einer Datenbank gespeichert ist, aber ich glaube nicht, das wirklich mit der Berechtigungsseite hilft. Ich habe bereits gelöst, die Frage des mit der folgenden SQL-Abfrage Berechtigungen gegen die einzelnen Datenbanken Überprüfung:

SELECT name 
FROM sys.databases 
WHERE HAS_DBACCESS(name) = 1 
ORDER BY name 

Vielen Dank für Ihre Hilfe!

-Jamie

Fazit

Im Wesentlichen habe ich keine Möglichkeit gefunden, die AD-Gruppen auf dem Remote-Server abzufragen, ohne zu versuchen, eine Verbindung herzustellen, so dass die Ausführung aller Proben gefunden wird das Benutzerkonto mit IA kennzeichnen. Für andere mit einem ähnlichen Problem, die sich nicht darum kümmern müssen, dass IA einen Hammer auf die Benutzer fallen lässt, habe ich ein paar Lösungen darunter eingefügt, die versuchen können, Ihre Anforderungen zu erfüllen (alle folgenden werden funktionieren, wenn sie korrekt implementiert werden).

Lösungen

  1. Abfrage der Server in Active Directory und die Gruppen vom Server abrufen, wenn diese 9mal Nachricht von zehn die Ausnahme versagt wird ‚Zugriff verweigert.‘.Wenn es erfolgreich ist, fahren Sie fort, die Gruppen des aktuellen Benutzers zu ziehen und mit den Gruppen zu vergleichen, die vom Server gezogen werden. Die ausgewählte Antwort auf diesen Beitrag kombiniert mit und/oder this post bringt Sie dorthin, wo Sie mit dieser Lösung sein müssen.
  2. Wenn Sie den Zugriff auf den Server haben bereits durch impersonation oder andere Mittel (SQL Server Auth), dann können Sie folgendes sehen verwenden, wenn das Mitglied zugeordnet alle Serverrollen hat:

    SELECT IS_SRVROLEMEMBER('public')

  3. Sie könnten auch Verwenden Sie das in der Microsoft.SqlServer.Smo-Assembly verfügbare Login class, das den Namespace Microsoft.SqlServer.Management.Smo verwendet. Sie haben jedoch möglicherweise Probleme, den Microsoft.SqlServer.SqlClrProvider-Namespace von dem GAC zu dem BIN zu verschieben. Weitere Informationen hierzu finden Sie unter this StackOverflow post und bei this Microsoft Connect Thread gefunden werden, die besagt Folgendes:

Client-Anwendungen sollten nicht die Baugruppen aus den Programmdateien-Ordner verwenden, sofern sie nicht von dem spezifischen SDK sind Ordner (zB "C: \ Program Files (x86) \ Microsoft SQL Server \ 130 \ SDK")

  1. Sie könnten einen grundlegenden Verbindungstest in einem selbst tun gewickelt versuchen Sie zu fangen, um zu sehen, ob die Verbindung funktioniert.

    using (SqlConnection conn = new SqlConnection(connString)) { try { conn.Open(); conn.Close(); } catch (Exception e) { Console.Write($"Connection test failed: {e.Message}"); } }

eine kleine Vielzahl von Möglichkeiten gibt es das übergeordnete Ziel zu erreichen, es kommt nur darauf an Ihrer Situation und wie wollen Sie es nähern. Für mich wird keine der Lösungen funktionieren, da der Test in jedem Szenario eine Verbindung zu dem fraglichen Server versucht, der den Benutzer aufgrund fehlender Berechtigungen kennzeichnet.

+0

Meinen Sie wollen Sie gegen Syslogins der einzelnen Server überprüfen? – SchmitzIT

+0

Ich muss überprüfen, ob ein Benutzer Zugriff auf einen Datenbankserver hat. Ich würde annehmen, dass es keine SQL-Abfragen gibt, aber es wäre schön, wenn es da wäre. Ich gehe davon aus, dass dies höchstwahrscheinlich eine Active Directory-Abfrage ist. – lxxtacoxxl

+0

Nun, sys.server_principals enthält Informationen darüber, welche Benutzer auf dem Server erstellt wurden. Sie können Ihre SQL Server immer abfragen, wenn sich ein Benutzer anmeldet, und nur diejenigen anzeigen, denen sie als Benutzer mit Zugriff hinzugefügt wurden. Nicht sicher, ob es einen besseren AD-Weg gibt, aber Sie müssen die beiden möglicherweise kombinieren, da SQL auch Mitglieder von Gruppen akzeptieren kann – SchmitzIT

Antwort

1

Wenn Sie Active Directory implementiert haben, sollten Sie Benutzern immer Zugriff auf Dinge wie Server über AD-Gruppen geben, sonst entsteht ein Management-Albtraum. Stellen Sie sich vor, wenn John Smith sich Ihrer Firma als Systemadministrator anschliesst, werden Sie zu jedem Server gehen und ihm explizit Rechte zuweisen? Es ist viel einfacher, eine AD-Gruppe für den Serveradministrator zu erstellen und sie dann dem Server zuzuweisen (oder diktieren, welche AD-Gruppen auf Servern und Berechtigungsstufen vorhanden sind).

Warum hilft Ihnen das auch, wenn Sie Anwendungen entwickeln? verwenden Sie die in AD Rollenanbieter gebaut Dinge wie diese servieren hier ein einfaches Beispiel ist ein Benutzer Gruppen von AD-Benutzernamen Grabbing

using System.DirectoryServices.AccountManagement; 

    public List<string> GetGroupNames(string userName) 
    { 
     List<string> result = new List<string>(); 
     using (PrincipalContext pc = new PrincipalContext(ContextType.Domain, "YOURDOMAINHERE")) 
     { 
      using (PrincipalSearchResult<Principal> src = UserPrincipal.FindByIdentity(pc, userName).GetGroups(pc)) 
      { 
       src.ToList().ForEach(sr => result.Add(sr.SamAccountName)); 
      } 
     } 
     return result; 
    } 

EDIT:. wenn Sie also absolut ablehnen Active Directory Gruppen verwenden, um Berechtigungen zu verwalten auf Servern und den Kauf eines Tools kommt nicht in Frage, hier ist eine Klasse, die durch alle Ihre lokalen Maschinengruppen iterieren und Ihnen eine Liste der Benutzer innerhalb dieser Gruppen geben wird.Sie können etwas wie eine geplante Aufgabe auf dem Server ausführen (oder einen Dienst gewinnen) und die Ergebnisse in einer Datenbank speichern, so dass Sie eine Benutzerschnittstelle abfragen oder erstellen können, um diese Informationen jederzeit abzurufen und zu überwachen. Dies reicht nicht aus und greifen Sie auf SQL-Server-Berechtigungen, wie Sie bereits sagten.

public class MachinePermissions 
{ 
    string machineName { get; set; } 
    public List<LocalGroup> localGroups { get; set; } 

    public List<string> GetGroupMembers(string sGroupName) 
    { 
     List<String> myItems = new List<String>(); 
     GroupPrincipal oGroupPrincipal = GetGroup(sGroupName); 
     PrincipalSearchResult<Principal> oPrincipalSearchResult = oGroupPrincipal.GetMembers(); 
     foreach (Principal oResult in oPrincipalSearchResult) 
     { 
      myItems.Add(oResult.Name); 
     } 
     return myItems; 
    } 

    private GroupPrincipal GetGroup(string sGroupName) 
    { 
     PrincipalContext oPrincipalContext = GetPrincipalContext(); 
     GroupPrincipal oGroupPrincipal = GroupPrincipal.FindByIdentity(oPrincipalContext, sGroupName); 
     return oGroupPrincipal; 
    } 

    private PrincipalContext GetPrincipalContext() 
    { 
     PrincipalContext oPrincipalContext = new PrincipalContext(ContextType.Machine); 
     return oPrincipalContext; 
    } 

    public MachinePermissions() 
    { 
     machineName = Environment.MachineName; 
     PrincipalContext ctx = new PrincipalContext(ContextType.Machine, Environment.MachineName); 
     GroupPrincipal gp = new GroupPrincipal(ctx); 
     gp.Name = "*"; 
     PrincipalSearcher ps = new PrincipalSearcher(); 
     ps.QueryFilter = gp; 
     PrincipalSearchResult<Principal> result = ps.FindAll(); 
     if(result.Count() > 0) 
     { 
      localGroups = new List<LocalGroup>(); 
      foreach (Principal p in result) 
      { 
       LocalGroup g = new LocalGroup(); 
       g.groupName = p.Name; 
       g.users = GetGroupMembers(g.groupName); 
       localGroups.Add(g); 
      } 
     } 
    } 
} 

public class LocalGroup 
{ 
    public string groupName { get; set; } 
    public List<String> users { get; set; } 
} 
+0

Active Directory ist ein sehr leistungsfähiges Werkzeug und macht das Leben in einer großen Umgebung extrem einfach für die Verwaltung. Mein Wissen darüber, wie es funktioniert, ist gut genug, aber wie die Informationen, die ich in meinem C# -Code benötige, zu ziehen, ist nicht. – lxxtacoxxl

+0

Welche Art von C# -Projekt erstellen Sie? –

+0

Am aussagekräftigsten ist, dass Servernamen aus einer bekannten Liste von Servern abgerufen werden. Anschließend werden alle Datenbanken, die keine Systemdatenbanken sind, von diesen Servern zur Anzeige an den Benutzer abgerufen. Die Auswahl der vollständigen Serverliste wäre ein potenzieller Albtraum für die Benutzer, da IA ​​ihre Konten sperren würde, wenn sie versuchen, sich mit Servern zu verbinden, auf die sie keinen Zugriff haben. Darüber hinaus sind die Beschreibungen, die ich geben kann, sehr, sehr, sehr eingeschränkt. – lxxtacoxxl

0

Sie können eine AD-Gruppe für den Zugriff auf jede Datenbank erstellen und ihnen dann Benutzer hinzufügen. In Ihrer App können Sie eine Liste von Gruppen hinzufügen und prüfen, ob der Benutzer Mitglied von ihnen ist.

Es ist allgemein üblich und ermöglicht die Erstellung sicherer Szenarien für unterschiedliche Zugriffsrechte für verschiedene Benutzer. Sie legen nur einmal Berechtigungen für die Gruppe fest und alle Mitglieder können von den Zugriffsrechten profitieren.

+0

AD kann in keiner Weise geändert werden. Sehr eingeschränkte Umgebung. Danke für die Idee! Vielleicht kann das jemandem in einer weniger eingeschränkten Umgebung als meinem eigenen helfen. – lxxtacoxxl

Verwandte Themen