Problem creating users programmatically in ASP.net - asp.net

For reference here is what my web.config and code look like:
<membership defaultProvider="SqlProvider" userIsOnlineTimeWindow="15">
<providers>
<clear />
<add name="SqlProvider"
type="System.Web.Security.SqlMembershipProvider"
connectionStringName="MySqlConnection"
applicationName="/"
enablePasswordRetrieval="false"
enablePasswordReset="true"
requiresQuestionAndAnswer="false"
requiresUniqueEmail="true"
passwordFormat="Hashed" />
</providers>
</membership>
VB code behind the fact:
Public Function Register(ByVal EncryptedName As String, ByVal EncryptedEmail As String) As String
Dim ret As String = ""
Try
Dim Provider As MembershipProvider = Membership.Providers.Item("SqlProvider")
Dim createStatus As MembershipCreateStatus
Dim newUser As MembershipUser = Provider.CreateUser(EncryptedName, Membership.GeneratePassword(8, 1), EncryptedEmail, "Your favorite color?", "RED", True, Guid.NewGuid, createStatus)
Select Case createStatus
Case MembershipCreateStatus.Success
ret = "The user account was successfully created!"
Case MembershipCreateStatus.DuplicateUserName
ret = "There already exists a user with this username."
Case MembershipCreateStatus.DuplicateEmail
ret = "There already exists a user with this email address."
Case MembershipCreateStatus.InvalidEmail
ret = "The email address provided is invalid."
Case MembershipCreateStatus.InvalidAnswer
ret = "The security answer is invalid."
Case MembershipCreateStatus.InvalidPassword
ret = "The password you provided is invalid. It must be seven characters long and have at least one non-alphanumeric character."
Case Else
ret = "There was an unknown error; the user account was NOT created."
End Select
Catch ex As Exception
Return "Server Error."
End Try
Return ret
End Function
For reference sake this is a webservice that we're using to allow users to register from our website and from desktop software. I don't know if it is the desktop software that is causing this problem. Right now I'm getting an exception on the create new user line. The exception says 'Login failed for 'DOMAIN/user' where DOMAIN is my work domain and user is my work login for my PC.
I've been looking around and found I needed to explicitly tell which provider to use (the provider checks out fine). I found a lot of samples where people simply used Membership.CreateUser but I found it wasn't loading the correct login.
I also tried playing with the authentication tag in the web.config.
The simple idea is to programmatically register new users through a webservice so it can be used with website and multiple in house desktop software applications.
Thanks for any help.

The membership provider is configured with a reference to a connection string. Have you confirmed it is a valid connection string? It sounds like your using the default one which will try to connect with integrated authentication. Also, the user being your login for your PC tells me either you're running from debug or IIS's application pool has an explicitly set identity.
That probably won't solve your problem, but, I wanted to offer what I could as I've had similar frustration in the past.

Related

PasswordReset() throws exception - passwordAnswer?

I have an app that I'm trying to implement the following, but can't seem to figure out how:
User signs up, but the system creates its own temporary password for them
Admin approves user and as part of that approval, the user gets sent a temporary username/password.
The problem is that I can't set the MembershipProvider to enable password retrieval as that seems to disable certficate authentication. I do have passwordReset enabled, but when I try to use it in step 2 (trying to create a new password so I can have it in plaintext to email it to the user), it throws an error:
General Error: System.Web.HttpUnhandledException (0x80004005): Exception of type 'System.Web.HttpUnhandledException' was thrown. ---> System.ArgumentNullException: Value cannot be null.
Parameter name: passwordAnswer
Is there any way around this?
Here's a code snippet of the relevant code:
MembershipUser mu = Membership.GetUser(Session["UserId"], false);
string password = mu.ResetPassword();
The password is null because nothing got entered. In your code, just use an if:
if (passwordAnswer==null){
//do stuff here
}
While you can write anything there, I recommend, maybe:
if (passwordAnswer==null){
passwordAnswer=" ";//just a space
}
If you want it to be a generated password, research on generating random alphanumeric strings.
I was able to circumvent this issue by adding requiresQuestionAndAnswer="false" to the membership provider in my web.config:
<membership defaultProvider="DefaultMembershipProvider">
<providers>
<add name="DefaultMembershipProvider"
type="System.Web.Security.SqlMembershipProvider"
requiresUniqueEmail="true"
connectionStringName="DB"
applicationName="Acme"
maxInvalidPasswordAttempts="3"
requiresQuestionAndAnswer="false"
enablePasswordReset="true"
minRequiredPasswordLength="15"
minRequiredNonalphanumericCharacters="1"
passwordAttemptWindow="3"
passwordFormat="Hashed" />
</providers>
</membership>

Membership.CreateUser keeps throwing 'InvalidAnswer'

I've been trying to use the CreateUser method to add users to my database. One thing I want is that password questions and answers aren't required, and so I have this in my Web.config:
membership>
<providers>
<clear/>
<add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider"
connectionStringName="CBCFXConnString"
enablePasswordRetrieval="false"
enablePasswordReset="true"
requiresQuestionAndAnswer="false"
requiresUniqueEmail="false"
maxInvalidPasswordAttempts="5"
minRequiredPasswordLength="8"
minRequiredNonalphanumericCharacters="0"
passwordAttemptWindow="10"
applicationName="CBCFX"/>
as you can see, I've set the requiresQuestionAndAnswer to false. This setting has been in my configuration ever since I started programming, and I am just dumbfounded as to why that InvalidAnswer persists when I try adding a user with this line:
fxSMP.CreateUser(userName, passWord, eMail, null, null, true, null, out status);
I've even tried passing empty strings to the question and answer arguments:
string pwQuestion = "";
string pwAnswer = "";
fxSMP.CreateUser(userName, passWord, eMail, pwQuestion, pwAnswer, true, null, out status);
but still nothing. What can I do to make this work?
EDIT: I've gone around the internet some more, and there appears to be an overload method wherein you could only input a UserName, Password and Email. Why does this overload not seem to be available in my instance of SqlMembershipProvider?
In your question I can't see how you are declaring the membership element in the web.config file but make sure you set the defaultProvider attribute...just in case. Also, I'd suggest you to use a different overload of the CreateUser method...
System.Web.Security.Membership.CreateUser(string username, string password, string email)
Edit
Now, since you are using the SqlMembershipProvider this overload will not be available. Why? First, because you are NOT supposed to be calling this method directly on your client code. You should rather use the Membership class. If you set the defaultProvider of the membership element in the web.config file and set the requiresQuestionAndAnswer to false then you shouldn't have any issues whatsoever.
By the way, check out this MSDN Documentation

How long does a session[] retain data?

I am trying to use a session but when i need the value back its null?
My website starts off with a login where i put the user name into a Session.
Session["userName"] = login.UserName;
Then the website is redirected to a new page.
return RedirectToAction("Choice", new { token = token });
after witch i use a link to move to my next page.
#Html.ActionLink("Download", "Download", new {token = Model.Token})
Where i direct my code to a action result in the Home controller, the same controller i have my login function.
#Html.ActionLink("Download", "DownloadFile", new { fileid = item.Key, token = Model.Token, platform = "windows", filename = item.Value }, new {#class = "DownloadLink" } )
Where i try call up my session value again.
formMobiApi.GetFile(token, fileid, platform, filename, Session["userName"].ToString(), tasks, taskId, spreadSheetStatus);
Are any of these actions doing anything to make my session value null?
Can i use a session like this?
If you are not manually setting your session state in web.config then the defaults you should have are in-process (sessions are stored in the RAM of the web server) and timeout is 20 minutes - see here for more information on session states.
You can manually set your states in your web.config file with the following:
<configuration>
<system.web>
<sessionState mode="InProc" timeout="20"></sessionState>
</system.web>
</configuration>
Now, onto your actual issue. I'm not exactly sure why your session isn't persisting and I can't feasibly find out as I don't have a copy of your code to debug. At a guess I'd say your HttpContext is different from when you initialized the session, to when you're requesting it and so your context key is different. Try changing
Session["userName"].ToString();
to
HttpContext.Current.Session["userName"].ToString();
This looks a little odd at first glance, as you're effectively doing the EXACT same thing. The difference comes down to if the current object doesn't have access to the HttpContext you need to explicitly define which context to read from.
Having taken another look at the code you've provided, there's nothing out of the ordinary - this should work. I really am starting to believe this is an environment / configuration issue. If you're using Form Authentication then check your timeout in your web.config file. Also, if you're hosting in IIS (and not Visual Studio's web server - although you should check this too!) try deleting your application pool and recreating it.
Your session variable is set up properly and it is being called properly to obtain the value.
The only thing left to debug is to actually see if login.UserName has an actually value. Because you might just be setting a session variable to null(login.UserName).
also try adding this to your web.config file if that doesn't work.
<sessionState mode="InProc" timeout="20" customProvider="DefaultSessionProvider">
<providers>
<add name="DefaultSessionProvider" type="System.Web.Providers.DefaultSessionStateProvider, System.Web.Providers, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" />
</providers>
</sessionState>

IIS Express references machine.config versus project web.config

I am writing a WsCF service to retrieve data for multiple clients. I have a service layer that references business manager objects. In essence on the service call, I want to retrieve the provider type (a custom enum in my code) and the connection string from the web.config.
For some reason, the code is unable to find the settings in my project web.config. I am gathering the IIS Express AND the VS development web server are referencing the machine.config. How do I override this. It is extremely frustrating. As you can see from the snippet the setting AND the connection string name exist, but the code never picks it up.
My code:
Private Sub GetDBInformation()
Dim config As System.Configuration.Configuration
config = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration(Nothing)
If (config.AppSettings.Settings.Count > 0) Then
Dim Setting As System.Configuration.KeyValueConfigurationElement
Setting = config.AppSettings.Settings("DB TYPE")
If Not (Setting.Value = Nothing) Then
Select Case Setting.Value
Case "SQL SERVER"
provider = ProviderType.SqlServer
Case Else
provider = ProviderType.OleDb
End Select
End If
End If
If (config.ConnectionStrings.ConnectionStrings.Count > 0) Then
connection = config.ConnectionStrings.ConnectionStrings("UMADB").ConnectionString
End If
End Sub
The web.config:
<connectionStrings>
<add name="UMADB"
connectionString="Data Source=***********;Initial Catalog=UMA;UserID=********;Password=***********"
providerName="System.Data.SqlClient" />
</connectionStrings>
<appSettings>
<add key="DB TYPE" value="SQL SERVER" />
</appSettings>
That's a really roundabout way of accessing the configuration settings. I don't know why or how you got to the machine.config, but there's an easier way.
Don't forget to import the System.Configuration namespace.
Dim Setting As String = ConfigurationSettings.AppSettings.Get("DB_TYPE")
If Not String.IsNullOrEmpty(DatabaseSetting) Then
Select Case Setting
Case "SQL SERVER"
provider = ProviderType.SqlServer
Case Else
provider = ProviderType.OleDb
End Select
End If
I don't know how or why you got to the machine.config, but that shouldn't happen. With your current approach, try specifying the application root when getting the configuration file:
System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~/")

How can I access UserId in ASP.NET Membership without using Membership.GetUser()?

How can I access UserId in ASP.NET Membership without using Membership.GetUser(username) in ASP.NET Web Application Project?
Can UserId be included in Profile namespace next to UserName (System.Web.Profile.ProfileBase)?
Try this:
MembershipUser CurrentUser = Membership.GetUser(User.Identity.Name);
Response.Write("CurrentUser ID :: " + CurrentUser.ProviderUserKey);
Is your reason for this to save a database call everytime you need the UserId? If so, when I'm using the ASP.NET MembershipProvider, I usually either do a custom provider that allows me to cache that call, or a utility method that I can cache.
If you're thinking of putting it in the Profile, I don't see much reason for doing so, especially as it also will still require a database call and unless you are using a custom profile provider there, it has the added processing of parsing out the UserId.
If you're wondering why they did not implement a GetUserId method, it's simply because you're not always guaranteed that that user id will be a GUID as in the included provider.
EDIT:
See ScottGu's article on providers which provides a link to downloading the actual source code for i.e. SqlMembershipProvider.
But the simplest thing to do really is a GetUserId() method in your user object, or utility class, where you get the UserId from cache/session if there, otherwise hit the database, cache it by username (or store in session), and return it.
For something more to consider (but be very careful because of cookie size restrictions): Forms Auth: Membership, Roles and Profile with no Providers and no Session
I decided to write authentication of users users on my own (very simple but it works) and I should done this long time ago.
My original question was about UserId and it is not available from:
System.Web.HttpContext.Current.User.Identity.Name
Try the following:
Membership.GetUser().ProviderUserKey
public string GetUserID()
{
MembershipUser _User;
string _UserId = "";
_User = Membership.GetUser();
Guid UserId = (Guid)_User.ProviderUserKey;
return _UserId = UserId.ToString();
}
You have two options here:
1) Use username as the primary key for your user data table
i.e:
select * from [dbo.User] where Username = 'andrew.myhre'
2) Add UserID to the profile.
There are pros and cons to each method. Personally I prefer the first, because it means I don't necessarily need to set up the out-of-the-box profile provider, and I prefer to enforce unique usernames in my systems anyway.
Andrew: I'd be careful of doing a query like what you've shown as by default, there's no index that matches with that so you run the risk of a full table scan. Moreover, if you're using your users database for more than one application, you haven't included the application id.
The closest index is aspnet_Users_Index which requires the ApplicationId and LoweredUserName.
EDIT:
Oops - reread Andrew's post and he's not doing a select * on the aspnet_Users table, but rather, a custom profile/user table using the username as the primary key.
I had this problem, the solution is in the web.config configuration, try configuring web.config with these:
<roleManager
enabled="true"
cacheRolesInCookie="true"
defaultProvider="QuickStartRoleManagerSqlProvider"
cookieName=".ASPXROLES"
cookiePath="/"
cookieTimeout="30"
cookieRequireSSL="false"
cookieSlidingExpiration="true"
createPersistentCookie="false"
cookieProtection="All">
<providers>
<add name="QuickStartRoleManagerSqlProvider"
type="System.Web.Security.SqlRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
connectionStringName="ASPNETDB"
applicationName="SecurityQuickStart"/>
</providers>
</roleManager>
{
MembershipUser m = Membership.GetUser();
Response.Write("ID: " + m.ProviderUserKey.ToString());
}
Will give you the UserID (uniqueidentifier) for the current user from the aspnet_Membership table - providing the current has successfully logged in. If you try to <%= %> or assign that value before a successful authentication you will get the error "Object reference not set to an instance of an object".
http://www.tek-tips.com/viewthread.cfm?qid=1169200&page=1
Have you tried using System.Web.HttpContext.Current.User.Identity.Name? (Make sure to verify that User and Identity are non-null first.)
internally it's executing below script in sql server
select * from vw_aspnet_MembershipUsers where USERNAME like '%username%'

Resources