Die letzten Tage bin ich über ein paar Probleme der ARS (Application Role Security) gestolpert und denke dass kann für den ein oder anderen interessant sein.
ARS ist ein mechnismus um Rechte Anwendungsspezifisch einschränken zu könnnen. So kann z.bsp. einen User das Recht genommen zuw erden ,daten in einer Tabelle zu ändern (Replace) aber sobald eine Anwendung sich durch eine AppRole Indentifiziert ist diese Anwendung unter dem angemeldeten User in der Lage Replaces auszuführen ohne dass es die Rechte des Users selbst ändert.
Zum aktivieren der AppRole Security für eine Verbindung muss man die sp_SetAppRole StoredProcedure am SQL Server ausführen. Wenn die Approle vorhanden ist und das Passwort stimmt, hat nun diese Verbindung alle Rechte die der Approle zugeordnet sind (ggf. mehr als der User selbst).
Leider musste ich aber Feststellen dass die AppRole kein Connection Pooling des ADO.NET unterstützt und sogar Fehler wirft. s.
SqlCommand appRoleCmd= null;
/// <summary>
/// Aktiviert die
Approle security mit den angegebenen Daten
/// </summary>
/// <param name="conn2Activate">Verbindung für die die Approle aktiviert werden soll.Muss
geöffnet sein</param>
/// <param name="appRole">name
der Approle</param>
/// <param
name="pw">Passwort der Approle</param>
/// <param
name="useEncryption">gibt an ob eine Verschlüsselung
verwendet wird</param>
/// <returns>Ergebnis vom
SQL Server kleiner 0 = Fehler 1 = OK! -99 = Keine Aktion ausgeführt,-100 =
Exception vom SQL Server, -101 Connection nicht vorhanden oder State != open
sonstiger wert kleiner 0 kommt vom SQL Servet</returns>
/// <remarks>Achtung
Approles & Verbindungspooling isnd nicht kompatibel s. :
http://msdn2.microsoft.com/de-de/library/8xx3tyca(VS.80).aspx &
http://support.microsoft.com/default.aspx?scid=kb;en-us;q229564</remarks>
public int ActivateApprole(IDbConnection conn2Activate, string appRole, string
pw, bool useEncryption)
{
int
result = -99;
if
(conn2Activate != null &&
conn2Activate.State == ConnectionState.Open)
{
//FAlls es das SQL Commando noch nicht gibt bauen wir
es uns passend zusammen. s. MSDN Doku
//Commando brauch nicht jedes mal neu erstellt zu
werden . so kann man verprofrmance spaten
if
(this.appRoleCmd== null)
{
this.appRoleCmd = new
SqlCommand("sp_setapprole",
conn2Activate as SqlConnection);
this.appRoleCmd.Parameters.Add("@rolename", SqlDbType.NVarChar);
this.appRoleCmd.Parameters.Add("@password", SqlDbType.NVarChar);
this.appRoleCmd.Parameters.Add("@encrypt", SqlDbType.NVarChar,
128);
this.appRoleCmd.CommandType = CommandType.StoredProcedure;
this.appRoleCmd.Parameters["@encrypt"].Value = "none";
}
else
{
this.appRoleCmd.Connection
= conn2Activate as SqlConnection;
}
//Nun übernehmen wir die übergebnen werde
this.appRoleCmd.Parameters["@password"].Value = pw;
this.appRoleCmd.Parameters["@rolename"].Value = appRole;
try
{
//Und führen die StoredProcedure aus
result
= this.appRoleCmd.ExecuteNonQuery();
}
catch
(Exception oErr)
{
//Aufrufen der Approlesecurity hat eine Ausnahme
ausgelöst
Debug.Assert(false,
oErr.ToString());
string Fehler = oErr.ToString();
//Result umsetzen damit ma ndifferenzieren kann wo er
fehler aufgeterten ist
result = -100;
}
}
else
{
//Verbindung ist nicht ovhranden oder nicht offen
result = -101;
}
return result;
}