Encountering error 'The Provider encountered an unknown error' while trying WebSecurity.CreateAccount in asp.net webpage - asp.net

I am new to asp.net. I am trying to create a simple login and register webpage with WebMatrix. But I get the following error when I try to create an account:
The Provider encountered an unknown error.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Web.Security.MembershipCreateUserException: The Provider encountered an unknown error.
Source Error:
Line 32: db.Execute("INSERT INTO UserData (Email,Name) VALUES (#0,#1)", email, username);
Line 33:
Line 34: WebSecurity.CreateAccount(email,password);
Line 35: Response.Redirect("Homepage.cshtml");
Line 36: }
Source File: c:\Users\admin\Documents\My Web Sites\Login\Register.cshtml Line: 34
Stack Trace:
[MembershipCreateUserException: The Provider encountered an unknown error.]
WebMatrix.WebData.SimpleMembershipProvider.CreateAccount(String userName, String password, Boolean requireConfirmationToken) +1312
WebMatrix.WebData.WebSecurity.CreateAccount(String userName, String password, Boolean requireConfirmationToken) +31
ASP._Page_Register_cshtml.Execute() in c:\Users\admin\Documents\My Web Sites\Login\Register.cshtml:34
System.Web.WebPages.WebPageBase.ExecutePageHierarchy() +207
System.Web.WebPages.WebPage.ExecutePageHierarchy(IEnumerable`1 executors) +68
System.Web.WebPages.WebPage.ExecutePageHierarchy() +156
System.Web.WebPages.StartPage.RunPage() +19
System.Web.WebPages.StartPage.ExecutePageHierarchy() +65
System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage) +76
System.Web.WebPages.WebPageHttpHandler.ProcessRequestInternal(HttpContextBase httpContext) +119
Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.272
Any help is appreciated. Thanks.

I just had the same issue ... I was using
WebSecurity.CreateAccount(model.UserName, model.Password);
and above generated issue ..
then I tried:
WebSecurity.CreateAccountAndUser(model.UserName, model.Password);
and find out that I was missing other required fields of my Users table (UserProfile). Following worked for me:
WebSecurity.CreateAccountAndUser(model.UserName, model.Password, new {RequiredColumn1 = Value1, RequiredColumn2 = Value 2, ...... });
The post is old, but hope this can help others..

Be sure to:
Create the User record first
Invoke WebMatrix to create the User account.
Below is my code which resolved the same issue you're having:
public ActionResult SignUp(SignUpModel model)
{
if (ModelState.IsValid)
{
using (MorphometryContext context = new MorphometryContext())
{
User user = new User
{
Email = model.Email,
FirstName = model.FirstName,
LastName = model.LastName,
Username = model.UserName
};
context.Users.Add(user);
context.SaveChanges();
}
// Attempt to register the user
try
{
WebSecurity.CreateAccount(model.UserName, model.Password);
}
catch (MembershipCreateUserException e)
{
ModelState.AddModelError("", ErrorCodeToString(e.StatusCode));
return View();
}
WebSecurity.Login(model.UserName, model.Password);
return RedirectToAction("Index", "Projects");
}
Also, you don't want to Respoonse.Redirect to a .cshtml file. Instead you should return a RedirectToAction and pass in the Action and Controller names.

I've just had this problem - but by your code it might not be the same thing. I was trying to create the membership record before creating the record in my own user table. It has to be the other way round.
So I'd check that your INSERT INTO UserData query was actually working.

In my case; It was because of Culture;
the Membership provider for creating account with CreateUserAndAccount function, first create a user. it is ok for now, and the user successfully added to the Database.
But for creating account, It runs the below query to get userID to create new account for it:
SELECT [userID] from [User] Where (UPPER([userName]) = #0);
Here is where exception thrown because in some culture upper casing the letters is different, for example in turkish, the upper case for 'i' is 'İ'.
I Don't know how to solve this problem for this moment, and I'll try to learn it.
In my case I was creating a user named "admin" and exception throw. I change the user name to "mesut" And it runs successfully.
please make sure if you have a culture specific letters in userName field.(or email in your case), (as soon as I found how to solve it I will post it here)

Related

InvalidOperationException: Role testRole does not exist

I was trying to let the accountController to assign roles to each newly registered user automatically, so I've ended up doing something like this:
public async Task<IActionResult> Register(RegisterViewModel model, string returnUrl = null)
{
if (ModelState.IsValid)
{
var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
var result = await _userManager.CreateAsync(user, model.Password);
//there is where the error is being raised.
await _userManager.AddToRoleAsync(user, "testRole");
if (result.Succeeded)
{
//here goes some code
//have also adding this line of code inside this if stmt
//await _userManager.AddToRoleAsync(user, "testRole");
}
AddErrors(result);
}
return View(model);
}
I did what other posts on StackOverFlow recommended but, I keep having this error:
InvalidOperationException: Role TESTROLE does not exist.
Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore+d__34.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
task)
Microsoft.AspNetCore.Identity.UserManager+d__104.MoveNext()
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
task) System.Runtime.CompilerServices.TaskAwaiter.GetResult()
WebApplication2.Controllers.AccountController+d__17.MoveNext()
in AccountController.cs
Notes:
I was using PostgreSql on my project, so I've created a new project
with MSSQL and ended up with the same error.
I've made sure that the testRole is being in the table AspNetRoles. So ,there's no problem with that either!
so testRole is exact name which would then get normalized to TESTROLE how was TestRole created? I say this because Identity looks for the normalized version. Exception is pretty clear that it doesn't exist in this case. Basically if you didn't use RoleManager then something is wrong with the way you created the role
Another way to create the role would be using your database context and add in new roles that way but if you didn't use caps for the NormalizedName field entry then this is the error you will get

DirectoryEntry SetPassword method returns Access Denied Exception

In an asp.net MVC application, i am encountering the Access denied error when trying to reset the password using directoryEntry.Invoke.
The page is accessed by the user trying to change his/her password and SSL required and Client Certificates - Required are marked in IIS.
Relevant code:
directoryEntry.Invoke("SetPassword", new object[] { model.Password });
directoryEntry.Properties["LockOutTime"].Value = 0;
directoryEntry.Close();
The exact error is –
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.UnauthorizedAccessException: Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
--- End of inner exception stack trace ---
at System.DirectoryServices.DirectoryEntry.Invoke(String methodName, Object[] args)
Web.config –
<authentication mode="Windows" />
<identity impersonate="false" />
<authorization>
<deny users="?" />
</authorization>
The app pool is running under an AD account; also part of the local
admin group [Domain1\AppPoolUser].
The application requests the user certificate
The user trying to change password [Domain2\testUser] and the account under which the app pool are running are in different domains but this is not likely an issue. Effective permissions for the AppPoolUser allows ChangePassword on the testUser account.
I even tried running the app pool under the same user account as the
test account but it doesn't change anything.
Have checked online but its not clear to me what the issue might be. The closest related thing i see is this - Setting ASP.Net Permissions - Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
However, as mentioned in my case the app pool is running under a limited technical account and i don't think there is any issue with SSL certificates.
Do i need to request Delegation of Control for the application pool account in the AD?
Or is there likely another issue that i m missing.
We had the similar requirement to change or reset the password. We use following code snippet.
/// <summary>
/// Resets the user password.
/// </summary>
public static void ResetUserPassword(string domain, string domainUsername, string domainPassword, string sAMAccountName, string newPassword,
bool askToChangePassword, bool unlockAccount, bool passRespectDomainPolicy, bool superuser)
{
// Get root directory entry
using (var entry = GetDirectoryEntry(domain, domainUsername, domainPassword, AuthenticationTypes.Secure))
{
var displayName = string.Empty;
// Search for the user with the same sAMAccountName
using (var searcher = new DirectorySearcher(entry))
{
// Filter results by SAMAccountName
searcher.Filter = string.Format("(SAMAccountName={0})", sAMAccountName);
// Search and return only one result
var result = searcher.FindOne();
// Check if result is returned
if (result == null) throw new Exception("Could not find user: " + sAMAccountName);
// Get the user directory entry
var userEntry = result.GetDirectoryEntry();
// Read name value
if (userEntry.Properties.Contains("displayName") && userEntry.Properties["displayName"].Count > 0)
displayName = Convert.ToString(userEntry.Properties["displayName"][0]);
// Validate password
// string errorMessage;
// if (passRespectDomainPolicy &&
// !IsValidPassword(domain, sAMAccountName, newPassword, displayName, userEntry, superuser, out errorMessage))
// {
// if (!string.IsNullOrEmpty(errorMessage)) throw new Exception(errorMessage);
// throw new Exception("Password is not valid as per AD policy. Please consult Administrator.");
// }
// Earlier we used impersonation to reset password on same DC.
// But that didn't worked and so removed.
userEntry.Invoke("SetPassword", newPassword);
// 0(for on) and -1(for off) for LDAP case. For WinNT it is opposite.
// Set "Ask to change password at next login"
if (askToChangePassword)
userEntry.Properties["pwdLastSet"].Value = 0;
// Unlock account if required
if (unlockAccount)
userEntry.Properties["lockoutTime"].Value = 0;
// Commit changes
userEntry.CommitChanges();
}
}
}
The noticeable point is that we are running the code userEntry.Invoke("SetPassword", newPassword); inside the context of root directory entry using (var entry = GetDirectoryEntry(domain, domainUsername, domainPassword, AuthenticationTypes.Secure)){.
I mean that entry represents the object holding the domain' administrator user and password. This administrator user must have full permission to make changes in AD.
Let us know your testing results.

Entity Framework .Net core FindAsync Throw System.OverflowException: Arithmetic operation resulted in an overflow

I'm trying to create a web API for authentication that return a token.
I'm using .Net core 1.1, EF 1.1.0 and SQL 2014 express on Windows 10. I follow direction from this website to create required classes.
In the middleware class, there's a function called GetIdentity to check the username and password in database. Here is the code
private async Task<ClaimsIdentity> GetIdentity(string username, string password, MyDBContext db) {
try
{
m_user SignedUser = await db.Users.FindAsync(username);
if (SignedUser == null || !SignedUser.password.Equals(password, StringComparison.Ordinal))
throw new ArgumentException("Invalid username or password");
return await Task.FromResult<ClaimsIdentity>(
new ClaimsIdentity(
new GenericIdentity(username, "Token"),
new Claim[] { }
));
}
catch (Exception ex) {Console.WriteLine(ex.Message); return await Task.FromResult<ClaimsIdentity>(null); }
}
When then program hit
m_user SignedUser = await db.Users.FindAsync(username);
It throws System.OverflowException: Arithmetic operation resulted in an overflow.
I didn't get any luck to find the solution or at least the reason why it failed.
Does anyone know why I got that exception?
Thank you for helping me.
P.S: If you need more information, just let me know
I fixed it. I used wrong connection string. I have to put the port number of SQL database in the connection string.
the wrong one:
Server=serverAddress;Database=dbName;User Id=dbUser;Password=dbPassword;
the right one:
Server=serverAddres,portNumber;Database=dbName;User Id=dbUser;Password=dbPassword;
Default MSSQL port number is 1433.
Hope it can help you out if you get same problem with me.
P.S you might get different exception. I got this exception when I tried to run it on VS Code
Like this one:
Microsoft.EntityFrameworkCore.Query.Internal.SqlServerQueryCompilationContextFactory[1] An exception occurred in the database while iterating the results of a query.

Sending email confirmation link in an ASP.Net application

I want to allow people by registering with their email id, password and confirming password in my asp.net 4.0 application. How can I send the confirmation link to their entered email, and there by showing the profile strength in their individual profiles? with the backend as sql server 2010
You have to send the confirmation link with unique confirmation id as query string parameter in link. When user clicks on that link you can validate that link for -
Is link already used?
Is link has valid confirmation number.
Then if it is valid link then allow user to confirm there email id. The unique confirmation id needs to be stored in the database for given email id. So that you can validate for it. Also in the same database table you can have additional field where it will record the time stamp when that id is generated and email send to user.
Introduction
Authentication and authorization as fundamental part of a web application was tremendously simplified with arrival of .NET 2.0. Basic authentication and authorization can be performed using different DBMS systems. There are numerous examples implementing authentication using Access database. One such example can be found in the article ASP.NET 2.0 Authentication using Access Database. In this article the example implements bare minimum to achieve desired goal, namely authentication and authorization using access database. However, authentication and authorization is only first part of the user management system. Second fundamental part of user management is allowing users to create an account at will. In such instances, users can sign up and become members of the community without administrator intervention. Furthermore, the user should be able to provide contact information (email) so that he/she can be contacted if necessary. Contact information must be verified. This article focuses on very simple ways to achieve such goal.
CreateUserWizard
As already suspected, .NET 2.0 provides necessary tools for quick and effective implementation of user registration. The component of interest is CreateUserWizard control that can be found under Login components. CreateUserWizard component provides preformatted set of components that provide the user with opportunity to enter necessary information. By default, CreateUserWizard provides user with option to enter name, password, email, security question, and answer to security question. In addition, CreateUserWizard provides the user with function to reenter the password to confirm user intentions.
In our example, we will focus on minimalistic approach to implement user signup and email conformation. As such we will not implement security question, but rather focus on username, password, and email to be confirmed. This article is continuation of ASP.NET 2.0 authorization using Access Database and it reuses Role and Membership provider code as presented in that article. Here, I’ll only present additions to the above mentioned article. In addition, full source code is included and demonstration can be found in demo section.
Extending Roles and Membership Providers
As already mentioned, I’ll focus on additional implementation necessary for CreateUserWizard implementation. Methods implemented in ASP.NET 2.0 authentication and authorization using Access Database are explained in mentioned article. However, there are some modifications that will be stressed at relevant time.
Looking at AccessMembershipProvider, I quickly realized that there are multiple methods that must be implemented to correctly use CreateUserWizardcontrol. First we need to be able to eliminate security question option. In order to eliminate security question, membership provider must return false for RequiresQuestionAndAnswer property of membership provider. Implementation of this property is similar to implementation of connection string property. We simply add variable of type bool that retrieves its value from web configuration file. Web configuration file must contain requiresQuestionAndAnswer as shown below:
<membership defaultProvider="AccessMembershipProvider">
<providers>
<clear/>
<add name="AccessMembershipProvider"
type="AccessProvider.AccessMembershipProvider"
connectionStringName="UsersDB"
requiresQuestionAndAnswer="false"/>
</providers>
</membership>
And the setting is parsed within Initialize method as following:
public override void Initialize(string name,
System.Collections.Specialized.NameValueCollection config)
{
base.Initialize(name, config);
m_strDBConnection =
ConfigurationManager.ConnectionStrings[config["connectionStringName"]].ConnectionString;
m_bRequiresQuestionAndAnswer =
(config["requiresQuestionAndAnswer"].ToLower().CompareTo("true") == 0);
}
As we can see, the code above simply extracts the setting from the web.config file and applies it to appropriate property. CreateUserWizard control reads the same property and displays security question according to the property value. Now that security question does not have to be entered, we can look at what happens when user enters the data and tries to create a user. Through experiment, I realized that the AccessMembershipProvider method CreateUser is called (obviously). Intuitively, I concluded that this method is responsible for the code that adds the user to the database. Following is method implementation:
public override MembershipUser CreateUser(string username, string password, string email,
string passwordQuestion, string passwordAnswer,
bool isApproved, object providerUserKey,
out MembershipCreateStatus status)
{
MembershipUser user = null;
using (OleDbConnection conn = new OleDbConnection(m_strDBConnection))
{
try
{
OleDbCommand command = new OleDbCommand("INSERT INTO Users " +
"(UUSERNAME, UPASSWORD, EMAIL, PROVIDER_KEY) "+
"VALUES (#Param1, #Param2, #Param3, #Param4)",
conn);
Guid guid = Guid.NewGuid();
command.Parameters.AddWithValue("#Param1", username);
command.Parameters.AddWithValue("#Param2", password);
command.Parameters.AddWithValue("#Param3", email);
command.Parameters.AddWithValue("#Param4", guid.ToString());
conn.Open();
command.ExecuteNonQuery();
string[] users = {username};
Roles.AddUsersToRole(users, "User");
conn.Close();
user = new MembershipUser("AccessMembershipProvider",
username, guid, email, null, null, false, false,
DateTime.Now, DateTime.Now, DateTime.Now,
DateTime.Now, DateTime.Now);
status = MembershipCreateStatus.Success;
}
catch (Exception ex)
{
System.Diagnostics.Trace.WriteLine(ex.Message);
status = MembershipCreateStatus.UserRejected;
}
}
return user;
}
CreateUser method simply adds the user to the database and returns MembershipUser object filled with the information as entered in CreateUserWizard. My first implementation of the method did not include adding the user to the “User” group using role provider. However, later investigation showed that the user was simply added without group assignment. Realizing that the user must be in a group, I added the following implementation to AccessRoleProvider code:
public override void AddUsersToRoles(string[] usernames, string[] roleNames)
{
using (OleDbConnection conn = new OleDbConnection(m_strDBConnection))
{
try
{
for (int i = 0; i < usernames.Length; ++i)
{
OleDbCommand command = new OleDbCommand("INSERT INTO UsersInRoles "+
"(ROLE_NAME, UUSERNAME) "+
"VALUES (#Param1, #Param2)",
conn);
command.Parameters.AddWithValue("#Param1", roleNames[i]);
command.Parameters.AddWithValue("#Param2", usernames[i]);
conn.Open();
command.ExecuteNonQuery();
conn.Close();
}
}
catch (Exception ex)
{
System.Diagnostics.Trace.WriteLine(ex.Message);
}
}
}
Now that the user is added to the database and assigned to appropriate group, we need to implement code to confirm user information, particularly email. Searching through MSDN documentation I found that CreateUserWizard provides method for automatic email notification. However, such approach was not appropriate because of lack of information provided within the event. Our conformation will utilize GUID that is written to DB when the user is created. The user will be activated only when the activation with such GUID is performed. Finding out GUID was impractical using send email event and easier solution was found, namely CreatedUser event of CreateUserWizard component.
Email Notification
As already mentioned, the user should be able to use the account only after successful email conformation. For conformation, the user should receive an email containing the link that will automatically activate the account. Once the account is activated, the account is ready to be used. Following is CreatedUser event implementation:
protected void CreateUserWizard1_CreatedUser(object sender, EventArgs e)
{
CreateUserWizard wizard = (CreateUserWizard)sender;
MembershipUser user = Membership.GetUser(wizard.UserName);
if (user != null)
{
try
{
SmtpClient smtpClient = new SmtpClient("smtpServer");
smtpClient.UseDefaultCredentials = true;
smtpClient.Send("yourEmail", user.Email, "Account Conformation Email",
"hst/Confirm.aspx?id="+user.ProviderUserKey.ToString());
}
catch (Exception ex)
{
System.Diagnostics.Trace.WriteLine(ex.Message);
}
}
}
Implementation of email notification is very simple. This is due to the fact that .NET library provides very simple means to communicate with any SMTP server. It is important to note the line smtpClient.UseDefaultCredentials = true. In this way, smtpClient object looks into web.config for SMTP server settings, i.e. username, password, and the host to be used. Following section is expected by SmtpClient object to be present in web.config file:
<system.net>
<mailSettings>
<smtp>
<network
host="smtp.hst.com "
userName="username"
password="password" />
</smtp>
</mailSettings>
</system.net>
Settings are self explanatory. The smtpClient simply needs the host name, username, and password to be used. Once the user is created, CreatedUser event is raised and email is sent. The content of the email is simply a link to Confirm.aspx page with an id parameter. The id parameter is GUID assigned specifically for that user. It is important to note that username could be used too, but GUID provides slightly more security.
Another extension necessary for CreatedUser event to function properly is capability of AccessMembershipProvider object to be able to provide user information based on username. In order to achieve such functionality, AccessMembershipProvider contains method that takes username as parameter and reads user information from database. Following is implementation:
public override MembershipUser GetUser(string username, bool userIsOnline)
{
MembershipUser user = null;
using (OleDbConnection conn = new OleDbConnection(m_strDBConnection))
{
try
{
/* Create command */
OleDbCommand command =
new OleDbCommand("SELECT UUSERNAME, PROVIDER_KEY, EMAIL FROM Users " +
"WHERE UUSERNAME=#Param1", conn);
command.Parameters.AddWithValue("#Param1", username);
/* Open connection */
conn.Open();
/* Run query */
OleDbDataReader reader = command.ExecuteReader();
/* Check if we have something */
bool bResult = reader.HasRows;
if (bResult)
{
reader.Read();
user = new MembershipUser("AccessMembershipProvider", reader.GetString(0),
new Guid(reader.GetString(1)),
reader.GetString(2), "", "", true, false,
DateTime.Now, DateTime.Now, DateTime.Now,
DateTime.Now, DateTime.Now);
}
/* Close connection */
conn.Close();
return user;
}
catch (Exception ex)
{
System.Diagnostics.Trace.WriteLine(ex.Message);
}
return user;
}
}
Once again, the implementation is trivial. We simply find info about user with specified username by running query against our users table.
Email Confirmation
Once the email is sent the user receives an email with a link to confirm his/her signup and email. The link is of the form http://"hst"/Confirm.aspx?id=XXXXXXXXXXXXXXXXXX, where XXXXXXXXXXXXXXXX is GUID determined in CreateUser method. Once the user clicks on the email the browser loads Confirm.aspx page with appropriate parameter. As suspected, Confirm.aspx is responsible for account activation. The account activation is performed by modifying ACTIVATED flag within user table. Following is Confirm.aspx implementation:
protected void Page_Load(object sender, EventArgs e)
{
if (Request.QueryString["id"] != null)
{
using (OleDbConnection conn = new OleDbConnection(
ConfigurationManager.ConnectionStrings["UsersDB"].ConnectionString))
{
try
{
OleDbCommand command =
new OleDbCommand("UPDATE Users SET ACTIVATED=#Param1 "+
"WHERE PROVIDER_KEY=#Param2", conn);
command.Parameters.AddWithValue("#Param1", true);
command.Parameters.AddWithValue("#Param2", Request.QueryString["id"]);
conn.Open();
command.ExecuteNonQuery();
conn.Close();
Response.Write("Your account has been activated. "+
"Please log in <a href='Default.aspx'>here</a>");
}
catch (Exception ex)
{
System.Diagnostics.Trace.WriteLine(ex.Message);
}
}
}
}
The implementation is self explanatory. The code simply modifies activated flag of the user with specified GUID.
At this point it is important to state somewhat obvious fact. The AccessMembershipProvider’s ValidateUser method must be modified to consider activated flag. In other words, only activated users can be validated and consequently logged in. For completeness, following is the implementation:
public override bool ValidateUser(string username, string password)
{
using (OleDbConnection conn = new OleDbConnection(m_strDBConnection))
{
try
{
/* Create command */
OleDbCommand command = new OleDbCommand("SELECT UUSERNAME, UPASSWORD FROM Users " +
"WHERE UUSERNAME=#Param1 " +
"AND UPASSWORD=#Param2 " +
"AND ACTIVATED=#Param3",
conn);
command.Parameters.AddWithValue("#Param1", username);
command.Parameters.AddWithValue("#Param2", password);
command.Parameters.AddWithValue("#Param3", true);
/* Open connection */
conn.Open();
/* Run query */
OleDbDataReader reader = command.ExecuteReader();
/* Check if we have something */
bool bResult = reader.HasRows;
/* Close connection */
conn.Close();
return bResult;
}
catch (Exception ex)
{
System.Diagnostics.Trace.WriteLine(ex.Message);
}
return false;
}
}
Access Database
Access database utilized is extended version of the database utilized in ASP.NET 2.0 Forms Authentication article with addition of GUID and ACTIVATED fields. GUID is stored in PROVIDER_KEY field. In addition, some fields like username and password had to be renamed because of the conflict with Access DB system.
Source
Click here to demo

Asp.net search Active Directory from IIS

Recently I moved my ASP.NET application from an old server running IIS5 to a new server running IIS7.5.
The application gives me an error:
The (&(objectCategory=person)(sAMAccountName=)) search filter is invalid.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.ArgumentException: The (&(objectCategory=person)(sAMAccountName=)) search filter is invalid.
The function that searches AD is:
public static string Get_AD_User_Email(string username)
{
try
{
DirectorySearcher searcher = new DirectorySearcher("(&(objectCategory=person)(sAMAccountName=" + username + "))");
SearchResult result = searcher.FindOne();
if (result != null)
{
DirectoryEntry employee = result.GetDirectoryEntry();
if (employee.Properties["mail"] != null)
{
return employee.Properties["mail"].Value.ToString();
}
else return "NULL";
}
else throw new Exception("ERROR: Problem searching active directory for users.");
}
catch (Exception ex) { throw ex; }
}
The weird thing is that on debug in Visual Studio the website is running, only from IIS it's crashes.
Can someone help me?
The trouble is just that your function Get_AD_User_Email(string username) is called with an empty value for username.
Since:
DirectorySearcher searcher = new DirectorySearcher("(&(objectCategory=person)(sAMAccountName=" + username + "))");
Is returning the exception:
The (&(objectCategory=person)(sAMAccountName=)) search filter is
invalid.
You are passing an empty string to Get_AD_User_Email.
How are you retrieving "username"?
You changed IIS servers, now no username is being passed in by the calling method (as several other answers point out).
I would verify that you have anonymous access disabled on that website in IIS. It's common to find both Windows authentication and anonymous access enabled. When this happens anonymous is preferred and you won't get the username.
Check the value of HttpContext.Current.User. I usually use code like the one below to verify windows authentication:
WindowsIdentity id = (WindowsIdentity)HttpContext.Current.User.Identity;
string username = id.Name;
Try:
objectClass=user
Instead of:
objectCategory=person

Resources