Miałem dokładnie to samo wymaganie. Miałem swój własny schemat roli i użytkownika i nie chciałem migrować do schematu członkostwa asp.net, ale chciałem użyć filtrów akcji ASP.NET MVC do sprawdzania autoryzacji i ról. Musiałem sporo kopać, żeby dowiedzieć się, co trzeba zrobić, ale w końcu było to stosunkowo łatwe. Uratuję ci kłopot i powiem ci, co zrobiłem.
1) Stworzyłem klasę wywodzącą się z System.Web.Security.MembershipProvider. MembershipProvider ma mnóstwo abstrakcyjnych metod dla wszelkiego rodzaju funkcji związanych z uwierzytelnianiem, takich jak zapomniane hasło, zmiana hasła, tworzenie nowego użytkownika itp. Wszystko, czego chciałem, to możliwość uwierzytelnienia na podstawie własnego schematu. Tak więc moja klasa zawierała głównie puste przesłonięcia. Właśnie overrode ValidateUser:
public override bool ValidateUser(string username, string password)
{
if (string.IsNullOrWhiteSpace(username) ||
string.IsNullOrWhiteSpace(password))
return false;
string hash = EncryptPassword(password);
User user = _repository.GetByUserName(username);
if (user == null) return false;
return user.Password == hash;
}
2) Stworzyłem klasę, że pochodzący z System.Web.Security.RoleProvider. Znowu miałem puste implementacje dla całego puchu, którego nie potrzebowałem, jak tworzenie i zmianę ról. Właśnie overrode dwie metody:
public override string[] GetRolesForUser(string username)
{
User user = _repository.GetByUserName(username);
string[] roles = new string[user.Role.Rights.Count + 1];
roles[0] = user.Role.Description;
int idx = 0;
foreach (Right right in user.Role.Rights)
roles[++idx] = right.Description;
return roles;
}
public override bool IsUserInRole(string username, string roleName)
{
User user = _repository.GetByUserName(username);
if(user!=null)
return user.IsInRole(roleName);
else
return false;
}
3) Następnie podłączyłem te dwie klasy do mojego web.config:
<membership defaultProvider="FirstlookMemberProvider" userIsOnlineTimeWindow="15">
<providers>
<clear/>
<add name="FirstlookMemberProvider" type="FirstlookAdmin.DomainEntities.FirstlookMemberProvider, FirstlookAdmin" />
</providers>
</membership>
<roleManager defaultProvider="FirstlookRoleProvider" enabled="true" cacheRolesInCookie="true">
<providers>
<clear/>
<add name="FirstlookRoleProvider" type="FirstlookAdmin.DomainEntities.FirstlookRoleProvider, FirstlookAdmin" />
</providers>
</roleManager>
to wszystko. Domyślne filtry akcji autoryzacji będą korzystać z tych klas. Nadal będziesz musiał zalogować się na stronie logowania i się wylogować. Po prostu używaj standardowych klas uwierzytelniania formularzy w taki sposób, jak zwykle.
+1. Dostosowanie dostawcy jest prawidłowym sposobem na zrobienie tego. Dziękuję za uwagę, że niekoniecznie musi to być dużo pracy. –
Och, warto zauważyć, że hasło powinno być naprawdę solone z dodatkiem przed haszowaniem. –
Przykro mi, że ożywam to i przeszkadzam, ale czy można uzyskać więcej informacji na temat rozwiązania? Jestem nieco zdezorientowany, jak radziłeś sobie z zarządzaniem rolą. – Ciel