Pour créer un fournisseur d'appartenances personnalisé J'ai suivi ces instructions:
How do I create a custom membership provider for ASP.NET MVC 2?
et ces:
http://mattwrock.com/post/2009/10/14/Implementing-custom-Membership-Provider-and-Role-Provider-for-Authinticating-ASPNET-MVC-Applications.aspxASP.NET MVC2 mise en œuvre personnalisée roleManager problème
Jusqu'à présent, je suis parvenu à mettre en œuvre fournisseur d'appartenances personnalisé et cette partie fonctionne bien. RoleManager a encore besoin de quelques modifications ...
Structure du projet:
alt text http://img691.imageshack.us/img691/3875/21593096.gif
SAMembershipProvider.cs:
public class SAMembershipProvider : MembershipProvider
{
#region - Properties -
private int NewPasswordLength { get; set; }
private string ConnectionString { get; set; }
public bool enablePasswordReset { get; set; }
public bool enablePasswordRetrieval { get; set; }
public bool requiresQuestionAndAnswer { get; set; }
public bool requiresUniqueEmail { get; set; }
public int maxInvalidPasswordAttempts { get; set; }
public int passwordAttemptWindow { get; set; }
public MembershipPasswordFormat passwordFormat { get; set; }
public int minRequiredNonAlphanumericCharacters { get; set; }
public int minRequiredPasswordLength { get; set; }
public string passwordStrengthRegularExpression { get; set; }
public override string ApplicationName { get; set; }
public override bool EnablePasswordRetrieval
{
get { return enablePasswordRetrieval; }
}
public override bool EnablePasswordReset
{
get { return enablePasswordReset; }
}
public override bool RequiresQuestionAndAnswer
{
get { return requiresQuestionAndAnswer; }
}
public override int MaxInvalidPasswordAttempts
{
get { return maxInvalidPasswordAttempts; }
}
public override int PasswordAttemptWindow
{
get { return passwordAttemptWindow; }
}
public override bool RequiresUniqueEmail
{
get { return requiresUniqueEmail; }
}
public override MembershipPasswordFormat PasswordFormat
{
get { return passwordFormat; }
}
public override int MinRequiredPasswordLength
{
get { return minRequiredPasswordLength; }
}
public override int MinRequiredNonAlphanumericCharacters
{
get { return minRequiredNonAlphanumericCharacters; }
}
public override string PasswordStrengthRegularExpression
{
get { return passwordStrengthRegularExpression; }
}
#endregion
#region - Methods -
public override void Initialize(string name, NameValueCollection config)
{
throw new NotImplementedException();
}
public override bool ChangePassword(string username, string oldPassword, string newPassword)
{
throw new NotImplementedException();
}
public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer)
{
throw new NotImplementedException();
}
public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
{
throw new NotImplementedException();
}
public override bool DeleteUser(string username, bool deleteAllRelatedData)
{
throw new NotImplementedException();
}
public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords)
{
throw new NotImplementedException();
}
public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords)
{
throw new NotImplementedException();
}
public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords)
{
throw new NotImplementedException();
}
public override int GetNumberOfUsersOnline()
{
throw new NotImplementedException();
}
public override string GetPassword(string username, string answer)
{
throw new NotImplementedException();
}
public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)
{
throw new NotImplementedException();
}
public override MembershipUser GetUser(string username, bool userIsOnline)
{
throw new NotImplementedException();
}
public override string GetUserNameByEmail(string email)
{
throw new NotImplementedException();
}
protected override void OnValidatingPassword(ValidatePasswordEventArgs e)
{
base.OnValidatingPassword(e);
}
public override string ResetPassword(string username, string answer)
{
throw new NotImplementedException();
}
public override bool UnlockUser(string userName)
{
throw new NotImplementedException();
}
public override void UpdateUser(MembershipUser user)
{
throw new NotImplementedException();
}
public override bool ValidateUser(string username, string password)
{
AccountRepository accountRepository = new AccountRepository();
var user = accountRepository.GetUser(username);
if (string.IsNullOrEmpty(password.Trim())) return false;
if (user == null) return false;
//string hash = EncryptPassword(password);
var email = user.Email;
var pass = user.Password;
if (user == null) return false;
if (pass == password)
{
//User = user;
return true;
}
return false;
}
#endregion
protected string EncryptPassword(string password)
{
//we use codepage 1252 because that is what sql server uses
byte[] pwdBytes = Encoding.GetEncoding(1252).GetBytes(password);
byte[] hashBytes = System.Security.Cryptography.MD5.Create().ComputeHash(pwdBytes);
return Encoding.GetEncoding(1252).GetString(hashBytes);
}
}
SARoleProvider.cs
public class SARoleProvider : RoleProvider
{
AccountRepository accountRepository = new AccountRepository();
public override bool IsUserInRole(string username, string roleName)
{
return true;
}
public override string ApplicationName
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
public override void AddUsersToRoles(string[] usernames, string[] roleNames)
{
throw new NotImplementedException();
}
public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
{
throw new NotImplementedException();
}
public override void CreateRole(string roleName)
{
throw new NotImplementedException();
}
public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
{
throw new NotImplementedException();
}
public override bool RoleExists(string roleName)
{
throw new NotImplementedException();
}
public override string[] GetRolesForUser(string username)
{
int rolesCount = 0;
IQueryable<RoleViewModel> rolesNames;
try
{
// get roles for this user from DB...
rolesNames = accountRepository.GetRolesForUser(username);
rolesCount = rolesNames.Count();
}
catch (Exception ex)
{
throw ex;
}
string[] roles = new string[rolesCount];
int counter = 0;
foreach (var item in rolesNames)
{
roles[counter] = item.RoleName.ToString();
counter++;
}
return roles;
}
public override string[] GetUsersInRole(string roleName)
{
throw new NotImplementedException();
}
public override string[] FindUsersInRole(string roleName, string usernameToMatch)
{
throw new NotImplementedException();
}
public override string[] GetAllRoles()
{
throw new NotImplementedException();
}
}
AccountRepository.cs
public class RoleViewModel
{
public string RoleName { get; set; }
}
public class AccountRepository
{
private DB db = new DB();
public User GetUser(string email)
{
return db.Users.SingleOrDefault(d => d.Email == email);
}
public IQueryable<RoleViewModel> GetRolesForUser(string email)
{
var result = (
from role in db.Roles
join user in db.Users on role.RoleID equals user.RoleID
where user.Email == email
select new RoleViewModel
{
RoleName = role.Name
});
return result;
}
}
webConfig
<membership defaultProvider="SAMembershipProvider" userIsOnlineTimeWindow="15">
<providers>
<clear/>
<add
name="SAMembershipProvider"
type="SA_Contacts.Membership.SAMembershipProvider, SA_Contacts"
connectionStringName ="ShinyAntConnectionString"
/>
</providers>
</membership>
<roleManager defaultProvider="SARoleProvider" enabled="true" cacheRolesInCookie="true">
<providers>
<clear/>
<add
name="SARoleProvider"
type="SA_Contacts.Membership.SARoleProvider"
connectionStringName ="ShinyAntConnectionString"
/>
</providers>
</roleManager>
AccountController.cs:
public class AccountController : Controller
{
SAMembershipProvider provider = new SAMembershipProvider();
AccountRepository accountRepository = new AccountRepository();
public AccountController()
{
}
public ActionResult LogOn()
{
return View();
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult LogOn(string userName, string password, string returnUrl)
{
if (!ValidateLogOn(userName, password))
{
return View();
}
var user = accountRepository.GetUser(userName);
var userFullName = user.FirstName + " " + user.LastName;
FormsAuthentication.SetAuthCookie(userFullName, false);
if (!String.IsNullOrEmpty(returnUrl) && returnUrl != "/")
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
public ActionResult LogOff()
{
FormsAuthentication.SignOut();
return RedirectToAction("Index", "Home");
}
private bool ValidateLogOn(string userName, string password)
{
if (String.IsNullOrEmpty(userName))
{
ModelState.AddModelError("username", "You must specify a username.");
}
if (String.IsNullOrEmpty(password))
{
ModelState.AddModelError("password", "You must specify a password.");
}
if (!provider.ValidateUser(userName, password))
{
ModelState.AddModelError("_FORM", "The username or password provided is incorrect.");
}
return ModelState.IsValid;
}
}
Dans certains contrôleur de test je suit:
[Authorize]
public class ContactsController : Controller
{
SAMembershipProvider saMembershipProvider = new SAMembershipProvider();
SARoleProvider saRoleProvider = new SARoleProvider();
//
// GET: /Contact/
public ActionResult Index()
{
string[] roleNames = Roles.GetRolesForUser("[email protected]");
// Outputs admin
ViewData["r1"] = roleNames[0].ToString();
// Outputs True
// I'm not even sure if this method is the same as the one below
ViewData["r2"] = Roles.IsUserInRole("[email protected]", roleNames[0].ToString());
// Outputs True
ViewData["r3"] = saRoleProvider.IsUserInRole("[email protected]", "admin");
return View();
}
Si j'utilise l'attribut [Authorize]
alors tout fonctionne bien, mais si j'utilise [Authorize(Roles="admin")]
alors l'utilisateur est toujours rejeté, comme s'il n'était pas dans le rôle.
Une idée de ce qui pourrait être mauvais ici?
Merci à l'avance,
Ile
Merci, je vais essayer demain matin! Je n'ai pas l'habitude d'utiliser des points d'arrêt, mais dans cet exemple c'est une bonne idée! –
altoguh, je ne pense pas que le problème est dans RoleExists parce que dans le tutoriel j'ai suivi le gestionnaire de rôles fonctionne et les mêmes implémentations de méthodes sont utilisées ...mais je verrai demain –
J'ai trouvé le problème grâce au débogage. Le problème était dans Controller dans la méthode LogOn. Il y a cette ligne: FormsAuthentication.SetAuthCookie (userFullName, false); et il a inséré un mauvais paramètre à cookie, au lieu de userFullName il est supposé être userName –