Users imported using UserManager.CreateUser() can't login
I imported users using the following method according to the 4.1 API documentation. Users added this way cannot login (using the login widget).
System.Web.Security.MembershipCreateStatus
User newUser = manager.CreateUser(userValues["user_name"],
userValues["passwd"],
userValues["email"],
"Question", "Answer",
true,
null,
out
status);
Which table stores role/user assignment? I'd like to verify the role assignments are correct.
Hello Suzanne,
Please try using the code below to create a user and assign it to a role. Since there is API exposed for working with user and roles I suggest that you should remove the SQL scripts. The code will create a single user and add it to administrators role so you should be able to authenticate yourself using the default membership and role providers. If you have custom membership and role providers you need to create instances of them, create the user and then configure the ProviderName of the public Login contorol
var userManager = UserManager.GetManager(
"Default"
);
System.Web.Security.MembershipCreateStatus status;
userManager.Provider.SuppressSecurityChecks =
true
;
var user = userManager.CreateUser(
"user1"
,
"user1234@"
,
"user1@test.com"
,
"Question"
,
"Answer"
,
true
,
null
,
out
status);
user.FirstName =
"FirstName"
;
user.LastName =
"LastName"
;
userManager.SaveChanges();
RoleManager roleManager = RoleManager.GetManager(
"AppRoles"
);
roleManager.Provider.SuppressSecurityChecks =
true
;
var role = roleManager.GetRole(
"Administrators"
);
roleManager.AddUserToRole(user, role);
roleManager.SaveChanges();
I'm not using SQL scripts - I used the API method you referenced to import the users. I'm not using a custom role provider either. Is there an API method I can call to get a reason for validation failing to help troubleshoot?
Hello Suzanne,
If you debug the code where you get the failure - when you call CrateUser or when you commit the transaction at the end?
You can put a breakpoint after you call the method and check whether the user object is null, so you can track which users are created or not. If one of the parameters in the method is not correct the user will not be created. In the membershipDataProvider there is a private method where we check these parameters.
If the provider RequiresUniqueEmail and you try to duplicate the user we will not create it. The same applies if the user exists
I crated a helper methods that you can add to your control to see whether one of the parameters you pass is not valid and when you call CreateUser you get false
protected
virtual
bool
ValidateParameters(
ref
string
userName,
ref
string
password,
ref
string
email,
ref
string
passwordQuestion,
ref
string
passwordAnswer,
ref
object
providerUserKey,
out
MembershipCreateStatus status)
var osdp =
new
OpenAccessMembershipProvider();
if
(
this
.RequiresUniqueEmail && osdp.EmailExists(email))
status = MembershipCreateStatus.DuplicateEmail;
return
false
;
if
(email ==
null
)
email = String.Empty;
if
(!osdp.UserExists(userName))
if
(providerUserKey !=
null
&& !(providerUserKey
is
Guid))
status = MembershipCreateStatus.InvalidProviderUserKey;
return
false
;
if
(providerUserKey ==
null
)
providerUserKey = Guid.NewGuid();
if
(passwordAnswer !=
null
)
passwordAnswer = passwordAnswer.Trim().ToUpperInvariant();
if
(!
string
.IsNullOrEmpty(passwordAnswer))
if
(passwordAnswer.Length > 0x80)
status = MembershipCreateStatus.InvalidAnswer;
return
false
;
if
(
this
.RequiresQuestionAndAnswer && String.IsNullOrEmpty(passwordAnswer))
status = MembershipCreateStatus.InvalidAnswer;
return
false
;
if
(passwordAnswer ==
null
)
passwordAnswer =
string
.Empty;
if
(String.IsNullOrEmpty(userName))
status = MembershipCreateStatus.InvalidUserName;
return
false
;
if
(
this
.RequiresQuestionAndAnswer && String.IsNullOrEmpty(passwordQuestion))
status = MembershipCreateStatus.InvalidQuestion;
return
false
;
if
(passwordQuestion ==
null
)
passwordQuestion = String.Empty;
if
(!
this
.ValidatePassword(password))
status = MembershipCreateStatus.InvalidPassword;
return
false
;
status = MembershipCreateStatus.Success;
return
true
;
else
status = MembershipCreateStatus.DuplicateUserName;
return
false
;
protected
virtual
bool
ValidatePassword(
string
password,
bool
throwException =
false
)
if
(password.Length <
this
.MinRequiredPasswordLength)
if
(throwException)
throw
new
ArgumentException(
string
.Format(Res.Get<SecurityResources>().PasswordTooShort,
this
.MinRequiredPasswordLength));
return
false
;
int
num = 0;
for
(
int
i = 0; i < password.Length; i++)
if
(!
char
.IsLetterOrDigit(password, i))
num++;
if
(num <
this
.MinRequiredNonAlphanumericCharacters)
if
(throwException)
throw
new
ArgumentException(
string
.Format(Res.Get<SecurityResources>().PasswordNeedsMoreAlphaNumericCharacters,
this
.MinRequiredNonAlphanumericCharacters));
return
false
;
// Valiate strength.
if
((
this
.PasswordStrengthRegularExpression.Length > 0) &&
!Regex.IsMatch(password,
this
.PasswordStrengthRegularExpression))
if
(throwException)
throw
new
ArgumentException(Res.Get<SecurityResources>().PasswordNeedsMoreAlphaNumericCharacters);
return
false
;
return
true
;
public
virtual
bool
RequiresQuestionAndAnswer
get
return
false
;
public
virtual
bool
RequiresUniqueEmail
get
return
true
;
public
virtual
int
MinRequiredPasswordLength
get
return
7;
public
virtual
int
MinRequiredNonAlphanumericCharacters
get
return
0;
public
virtual
string
PasswordStrengthRegularExpression
get
return
String.Empty;
I don't want to re-import if I don't have to. The users were created successfully - I can access them in the backend (Admin-> Users). They just can't login using the login widget and I don't know why - if it's invalid password, or field in the database is not set correctly. Is there a field(s) to look at in the database to determine if something is set incorrectly?
Hi Suzanne,
Have you checked User-Role relation in [sf_user_link] table ? Have you granted the role with backend access?
Kind regards,
Ivan Dimitrov
the Telerik team
Hi Suzanne,
Just assign the user to administrators role as the first post to you shows to see whether the issue is role related. This code works, so you can use it to narrow down the issue at your end.
Best wishes,
Ivan Dimitrov
the Telerik team
No, we specifically didn't assign these users to Backend role. So in order to use the Login Widget, a user has to be assigned to Backend role?
If we create a custom login control, is there an overloaded ValidateUser() method I can call that doesn't require user to be in Backend role?
Figured out what was causing invalid login - two fields in the database were not populated correctly.
1) password_format was set to 0, changed to 1
2) last_lockout_date was being populated during my import and I noticed it was null for other users I created through the admin. When I set that value null, the login worked.