Re: ADAM and AuthorizationStoreRoleProvider



Hello,

This post contains code for a RoleProvider that allows you to assign
ADAM roles to ADAM users only.

To make it work, just paste it into a new cs file, add a reference to
the Microsoft.Interop.Security.AzRoles dll
I hope someone with knowledge of ADAM and/or Active Directory will
assist in completing the last two methods of this provider!

Here's the code for so far:

==========================================

using System.Web.Security;
using System.Configuration.Provider;
using System.Collections.Specialized;
using System.Collections;
using System;
using System.Resources;
using System.Data;
using System.Data.Odbc;
using System.Configuration;
using System.Diagnostics;
using System.Web;
using System.Security;
using System.Globalization;
using Microsoft.Interop.Security;
using Microsoft.Interop.Security.AzRoles;
using System.Security.Principal;
using System.DirectoryServices;
using System.Runtime.InteropServices;

namespace InSumma.Security.Adam.Roles
{
/// <summary>
/// Implementation of a .NET 2.0 Role Provider that supports
/// assigning roles to ADAM users. The standard AzMan Role Provider
/// only supports assigning roles to Windows Users.
/// </summary>
public sealed class AdamRoleProvider : RoleProvider
{
//
// Global connection string, generic exception message, event
log info.
//
private string eventSource = "AdamRoleProvider";
private string eventLog = "Application";
private string exceptionMessage = "Er is een fout opgetreden in
de RoleProvider. Meer details staan in de Event Log.";

private string azManApplicationName="";
private ConnectionStringSettings pConnectionStringSettings;
private string azManConnectionString="";


//
// If false, exceptions are thrown to the caller. If true,
// exceptions are written to the event log.
//

private bool pWriteExceptionsToEventLog = false;

public bool WriteExceptionsToEventLog
{
get { return pWriteExceptionsToEventLog; }
set { pWriteExceptionsToEventLog = value; }
}



//
// System.Configuration.Provider.ProviderBase.Initialize Method
//

public override void Initialize(string name,
NameValueCollection config)
{
//
// Initialize values from web.config.
//
System.Diagnostics.TextWriterTraceListener twtl = new
TextWriterTraceListener(@"c:\AdamRoleProvider.txt");
System.Diagnostics.Trace.Listeners.Add(twtl);
System.Diagnostics.Trace.WriteLine("AdamRoleProvider:
Initialize");
System.Diagnostics.Trace.Flush();

if (config == null)
throw new ArgumentNullException("config");

if (name == null || name.Length == 0)
name = "AdamRoleProvider";

if (String.IsNullOrEmpty(config["description"]))
{
config.Remove("description");
config.Add("description", "Role Provider supporting
assignment of roles to ADAM users");
}

// Initialize the abstract base class.
base.Initialize(name, config);


if (config["applicationName"] == null ||
config["applicationName"].Trim() == "")
azManApplicationName =
System.Web.Hosting.HostingEnvironment.ApplicationVirtualPath;
else
azManApplicationName = config["applicationName"];


if (config["writeExceptionsToEventLog"] != null)
{
if (config["writeExceptionsToEventLog"].ToUpper() ==
"TRUE")
{
pWriteExceptionsToEventLog = true;
}
}

//
// Initialize AdamRoleProvider
//

// Read connectionstring only if it's not yet set by the
property
if (azManConnectionString=="")
{
pConnectionStringSettings =
ConfigurationManager.ConnectionStrings[config["connectionStringName"]];
if (pConnectionStringSettings == null ||
pConnectionStringSettings.ConnectionString.Trim() == "")
throw new ProviderException("AdamRoleProvider
connection string cannot be blank.");
azManConnectionString =
pConnectionStringSettings.ConnectionString;
}
}


//
// Allow to set a connectionstring by code (for testing)
//
public string ConnectionString
{
set { azManConnectionString = value; }
}


//
// System.Web.Security.RoleProvider properties.
//
public override string ApplicationName
{
get { return azManApplicationName; }
set { azManApplicationName = value; }
}


#region Implementation of AdamRoleProvider
//
// System.Web.Security.RoleProvider methods.
//

//
// RoleProvider.AddUsersToRoles
//

public override void AddUsersToRoles(string[] usernames,
string[] rolenames)
{
// Show entry of method
System.Diagnostics.Trace.WriteLine("AdamRoleProvider:
AddUsersToRoles");
System.Diagnostics.Trace.Flush();

// Check for duplicate roles
foreach (string rolename in rolenames)
{
if (!RoleExists(rolename))
throw new ProviderException("Role name not
found.");
}

foreach (string username in usernames)
{
if (username.IndexOf(',') > 0)
throw new ArgumentException("User names cannot
contain commas.");

foreach (string rolename in rolenames)
{
if (IsUserInRole(username, rolename))
throw new ProviderException("User is already in
role.");
}
}


try
{
// Connect to the ADAM store
IAzApplication _azApp = GetAdamApp();

// Loop users and roles
foreach (string username in usernames)
{
MembershipUser user = Membership.GetUser(username);

foreach (string rolename in rolenames)
{
IAzRole role = _azApp.OpenRole(rolename, null);
role.AddMember(user.ProviderUserKey.ToString(),
null);
role.Submit(0, null);
}
}
}
catch (Exception e)
{
if (WriteExceptionsToEventLog)
WriteToEventLog(e, "AddUsersToRoles");
else
throw e;
}
}


//
// RoleProvider.CreateRole
//

public override void CreateRole(string rolename)
{
// Show entry of method
System.Diagnostics.Trace.WriteLine("AdamRoleProvider:
CreateRole");
System.Diagnostics.Trace.Flush();

// Check precondition
if (rolename.IndexOf(',') > 0)
throw new ArgumentException("Role names cannot contain
commas.");

if (RoleExists(rolename))
throw new ProviderException("Role name already
exists.");

try
{
// Connect to the ADAM store
IAzApplication _azApp = GetAdamApp();

// Add a role
IAzTask task = _azApp.CreateTask(rolename, null);
task.IsRoleDefinition = 1;
task.Submit(0, null);

IAzRole role = _azApp.CreateRole(rolename, null);
role.AddTask(rolename, null);
role.Submit(0, null);
}
catch (Exception e)
{
if (WriteExceptionsToEventLog)
WriteToEventLog(e, "CreateRole");
else
throw e;
}
}


//
// RoleProvider.DeleteRole
//

public override bool DeleteRole(string rolename, bool
throwOnPopulatedRole)
{
// Show entry of method
System.Diagnostics.Trace.WriteLine("AdamRoleProvider:
DeleteRole");
System.Diagnostics.Trace.Flush();

// Check preconditions
if (!RoleExists(rolename))
throw new ProviderException("Role does not exist.");

if (throwOnPopulatedRole && GetUsersInRole(rolename).Length
0)
throw new ProviderException("Cannot delete a populated
role.");

try
{
// Connect to the ADAM store
IAzApplication _azApp = GetAdamApp();

// Delete a role
_azApp.DeleteTask(rolename, null);
_azApp.Submit(0, null);

_azApp.DeleteRole(rolename, null);
_azApp.Submit(0, null);
}
catch (Exception e)
{
if (WriteExceptionsToEventLog)
{
WriteToEventLog(e, "DeleteRole");
return false;
}
else
throw e;
}

return true;
}


//
// RoleProvider.GetAllRoles
//

public override string[] GetAllRoles()
{
// Show entry of method
System.Diagnostics.Trace.WriteLine("AdamRoleProvider:
GetAllRoles");
System.Diagnostics.Trace.Flush();

try
{
// Connect to the ADAM store
IAzApplication _azApp = GetAdamApp();

int i = 1;
string[] roles = new string[_azApp.Roles.Count];
while (i <= _azApp.Roles.Count)
{
IAzRole role = (IAzRole)_azApp.Roles[i];
roles[i-1] = role.Name;
i++;
}

return roles;
}
catch (Exception e)
{
if (WriteExceptionsToEventLog)
WriteToEventLog(e, "GetAllRoles");
else
throw e;
}

return new string[0];
}


//
// RoleProvider.GetRolesForUser
//

public override string[] GetRolesForUser(string username)
{
// Show entry of method
System.Diagnostics.Trace.WriteLine("AdamRoleProvider:
GetRolesForUser");
System.Diagnostics.Trace.Flush();

try
{
throw new NotSupportedException("GetRolesForUser is not
supported by the AdamRoleProvider");

//TODO Implement this method!!!

}
catch (Exception e)
{
if (WriteExceptionsToEventLog)
WriteToEventLog(e, "GetRolesForUser");
else
throw e;
}

return new string[0];
}


//
// RoleProvider.GetUsersInRole
//

public override string[] GetUsersInRole(string rolename)
{
// Show entry of method
System.Diagnostics.Trace.WriteLine("AdamRoleProvider:
GetUsersInRole");
System.Diagnostics.Trace.Flush();

try
{
// Connect to the ADAM store
IAzApplication _azApp = GetAdamApp();

IAzRole role = _azApp.OpenRole(rolename, null);
if (role == null) throw new ProviderException("Role
"+rolename+" was not found");

object[] members = (object[]) role.Members;
string[] usernames = new string[members.Length];

int i = 1;
while(i <= members.Length)
{
usernames[i-1] = members[i-1].ToString();
i++;
}
}
catch (Exception e)
{
if (WriteExceptionsToEventLog)
WriteToEventLog(e, "GetUsersInRole");
else
throw e;
}

return new string[0];
}


//
// RoleProvider.IsUserInRole
//

public override bool IsUserInRole(string username, string
rolename)
{
// Show entry of method
System.Diagnostics.Trace.WriteLine("AdamRoleProvider:
IsUserInRole");
System.Diagnostics.Trace.Flush();

try
{
string[] roles = GetRolesForUser(username);
foreach(string role in roles)
{
if (role==rolename)
return true;
}
}
catch (Exception e)
{
if (WriteExceptionsToEventLog)
WriteToEventLog(e, "IsUserInRole");
else
throw e;
}

return false;
}


//
// RoleProvider.RemoveUsersFromRoles
//

public override void RemoveUsersFromRoles(string[] usernames,
string[] rolenames)
{
// Show entry of method
System.Diagnostics.Trace.WriteLine("AdamRoleProvider:
RemoveUsersFromRoles");
System.Diagnostics.Trace.Flush();

foreach (string rolename in rolenames)
{
if (!RoleExists(rolename))
throw new ProviderException("Role name not
found.");
}

foreach (string username in usernames)
{
foreach (string rolename in rolenames)
{
if (!IsUserInRole(username, rolename))
throw new ProviderException("User is not in
role.");
}
}


try
{
IAzApplication _azApp = GetAdamApp();
foreach (string username in usernames)
{
MembershipUser user = Membership.GetUser(username);

foreach (string rolename in rolenames)
{
IAzRole role = _azApp.OpenRole(rolename, null);

role.DeleteMember(user.ProviderUserKey.ToString(), null);
role.Submit(0, null);
}
}
}
catch (Exception e)
{
if (WriteExceptionsToEventLog)
WriteToEventLog(e, "RemoveUsersFromRoles");
else
throw e;
}
}


//
// RoleProvider.RoleExists
//

public override bool RoleExists(string rolename)
{
// Show entry of method
System.Diagnostics.Trace.WriteLine("AdamRoleProvider:
RoleExists");
System.Diagnostics.Trace.Flush();

bool exists = false;
try
{
IAzApplication _azApp = GetAdamApp();

// Warning! The Roles collection is 1-bases instead of
0-based!!
int i = 1;
while (i <= _azApp.Roles.Count && !exists)
{
IAzRole role = (IAzRole)_azApp.Roles[i];
if (role.Name == rolename)
exists = true;
i++;
}
}
catch (Exception ex)
{
if (WriteExceptionsToEventLog)
WriteToEventLog(ex, "RoleExists");
else
throw ex;
}

return exists;
}

//
// RoleProvider.FindUsersInRole
//

public override string[] FindUsersInRole(string rolename,
string usernameToMatch)
{
// Show entry of method
System.Diagnostics.Trace.WriteLine("AdamRoleProvider:
FindUsersInRole");
System.Diagnostics.Trace.Flush();

try
{
throw new NotSupportedException("FindUsersInRole is not
supported by the AdamRoleProvider");

//TODO Implement this method!!!

}
catch (Exception e)
{
if (WriteExceptionsToEventLog)
WriteToEventLog(e, "FindUsersInRole");
else
throw e;
}

return new string[0];
}

#endregion


#region Support methods

//
// WriteToEventLog
// A helper function that writes exception detail to the
event log. Exceptions
// are written to the event log as a security measure to avoid
private database
// details from being returned to the browser. If a method does
not return a status
// or boolean indicating the action succeeded or failed, a
generic exception is also
// thrown by the caller.
//

private void WriteToEventLog(Exception e, string action)
{
EventLog log = new EventLog();
log.Source = eventSource;
log.Log = eventLog;

string message = exceptionMessage + "\n\n";
message += "Action: " + action + "\n\n";
message += "Exception: " + e.ToString();

log.WriteEntry(message);
}


/// <summary>
/// Initializes communication with ADAM
/// </summary>
/// <returns>A reference to the ADAM application</returns>
private IAzApplication GetAdamApp()
{
AzAuthorizationStore _azStore = new
AzAuthorizationStoreClass();
_azStore.Initialize(0, azManConnectionString, null);
IAzApplication _azApp =
_azStore.OpenApplication(azManApplicationName, null);
return _azApp;
}

#endregion

}
}

.



Relevant Pages

  • Re: Dynamic QueryString!
    ... > Hi Adam, ... > The function would be of type string and receive the dataitem as a string ... > Ken Dopierala Jr. ... >> I am wanting to url the HyperLink server control in a datagrid. ...
    (microsoft.public.dotnet.framework.aspnet)
  • Re: Roles in membership database
    ... private void MapUsersToRoles() ... foreach (string userAndRole in this._toDoUserAndRoleValues) ... if (!Roles.IsUserInRole (userName, roleName)) ... Roles.AddUsersToRole(new string{userName}, ...
    (microsoft.public.dotnet.framework.aspnet)
  • Re: AD/ADAM Create User (VB.Net)
    ... There are also a few ADAM specific things to do here. ... the application partition NC Name in your binding string in order for LDAP ... strUserPrincipalName) ... Dim firstname As String = "user" ...
    (microsoft.public.windows.server.active_directory)
  • Re: AD/ADAM Create User (VB.Net)
    ... I'm confused about Active Directory and ADAM - they appear to be ... the application partition NC Name in your binding string in order for LDAP ... strUserPrincipalName) ... Dim firstname As String = "user" ...
    (microsoft.public.windows.server.active_directory)
  • Re: Authenticating Web user and domain User with ADAM
    ... Whit this System.Web configuration of my web.config file I'm able to ... connect to My adam partition. ... classOBJ the name of the class to be used to create the entry ... string classObj, string pwd) ...
    (microsoft.public.windows.server.active_directory)