Y a-t-il des fournisseurs d'appartenances asp.net personnalisés que quelqu'un a déjà créés en ligne? Je souhaite utiliser un fournisseur personnalisé car leur fournisseur de rôles est très lent et j'aimerais utiliser des entiers au lieu de guids pour les ID utilisateurASP.NET: Où puis-je trouver un fournisseur d'appartenances personnalisées rapide
Répondre
Il ne peut pas y avoir d'autres implémentations de l'API du fournisseur d'appartenances standard, étant donné qu'elle est basée sur interfaces non génériques. Cependant, en pratique, l'API d'adhésion complète ajoute très peu de valeur et il est assez facile de rouler votre propre solution.
Pour vous aider à démarrer voici quelques-unes des classes auxiliaires que j'utilise généralement.
D'abord, un code pour traiter avec l'authentification des cookies et formulaires:
public interface ISecurityPersistenceProvider
{
void SetAuthCookie(int version, string name, DateTime expireDate, bool persistent, string cookieData);
HttpCookie GetAuthCookie();
string GetAuthCookieValue(out string name);
void RemoveAuthCookie();
}
public class FormsPersistenceProvider : ISecurityPersistenceProvider
{
public void SetAuthCookie(int version, string name, DateTime expireDate, bool persistent, string cookieData)
{
var ticket = new FormsAuthenticationTicket(version, name, DateTime.Now, expireDate, persistent, cookieData);
string secureTicket = FormsAuthentication.Encrypt(ticket);
var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, secureTicket);
cookie.Expires = ticket.Expiration;
HttpContext.Current.Response.Cookies.Add(cookie);
}
public HttpCookie GetAuthCookie()
{
HttpCookie cookie = HttpContext.Current.Request.Cookies[ FormsAuthentication.FormsCookieName ];
return cookie;
}
public string GetAuthCookieValue(out string name)
{
HttpCookie cookie = GetAuthCookie();
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(cookie.Value);
name = ticket.Name;
return ticket.UserData;
}
public void RemoveAuthCookie()
{
FormsAuthentication.SignOut();
}
}
En second lieu, un code pour valider les utilisateurs contre un magasin de données. Vous devrez fournir votre propre implémentation pour cette interface (et/ou l'adapter à vos besoins).
public interface ISecurityUserProvider<T> where T : class
{
T AuthenticateUser(string customer, string userName, string passwordHash);
T GetUser(string customer, string userName);
string[] GetRoles(T user);
}
Troisièmement, une classe pour nous faire renvoyer des informations supplémentaires aux appelants (ce qui sera utilisé par la classe SecurityManager ci-dessous):
public class AuthenticationResult
{
#region Fields/Properties
public bool Success { get; internal set; }
public string Message { get; internal set; }
public IDictionary<string,string> Errors { get; internal set; }
#endregion
#region Constructors
public AuthenticationResult(bool success, string message) : this(success, message, null)
{
}
public AuthenticationResult(bool success, string message, IDictionary<string, string> errors)
{
Success = success;
Message = message;
Errors = errors ?? new Dictionary<string, string>();
}
#endregion
}
J'utilise aussi une classe principale personnalisée qui me permet associer un objet personnalisé à l'implémentation IPrincipal de base. Ceci est juste un extrait rapide pour vous donner l'idée:
public class CodeworksPrincipal<TUserData> : IPrincipal where TUserData : class
{
private string name;
private string[] roles;
private string allRoles;
private TUserData userData;
public CodeworksPrincipal(string name, string[] roles, TUserData userData)
{
// init fields, etc.
}
}
Et enfin, la classe SecurityManager avec la majeure partie de la logique:
public class SecurityManager<T,TPersistenceProvider,TUserProvider>
where T : class
where TPersistenceProvider : ISecurityPersistenceProvider
where TUserProvider : ISecurityUserProvider<T>
{
private readonly ISecurityPersistenceProvider persistenceProvider;
private readonly ISecurityUserProvider<T> userProvider;
// NOTE this constant is used to validate the validity of the cookie (see below)
private const int CookieParameterCount = 3;
public SecurityManager(ISecurityPersistenceProvider persistenceProvider, ISecurityUserProvider<T> userProvider)
{
this.persistenceProvider = persistenceProvider;
this.userProvider = userProvider;
}
#region Properties
protected ISecurityPersistenceProvider PersistenceProvider
{
get { return persistenceProvider; }
}
protected ISecurityUserProvider<T> UserProvider
{
get { return userProvider; }
}
public IIdentity CurrentIdentity
{
get { return Thread.CurrentPrincipal.Identity; }
}
public bool IsAuthenticated
{
get
{
IPrincipal principal = Thread.CurrentPrincipal;
return principal != null && principal.Identity != null && principal.Identity.IsAuthenticated;
}
}
public bool IsInRole(string roleName)
{
IPrincipal principal = Thread.CurrentPrincipal;
return IsAuthenticated && principal.IsInRole(roleName);
}
public string UserName
{
get { return IsAuthenticated ? CurrentIdentity.Name : ""; }
}
#endregion
#region Authentication
public AuthenticationResult Authenticate(string userName, string password, bool persistent, string visitorAddress)
{
return Authenticate(null, userName, password, persistent, visitorAddress);
}
public AuthenticationResult Authenticate(string customer, string userName, string password, bool persistent, string visitorAddress)
{
AuthenticationResult result = ValidateInput(userName, password);
if(! result.Success)
return result;
string passwordHash = GetCryptographicHash(password);
T user = userProvider.AuthenticateUser(customer, userName, passwordHash);
if(user == null)
return new AuthenticationResult(false, "Unable to login using the specified credentials.", null);
if(! IsAuthorizedVisitor(user, visitorAddress))
return new AuthenticationResult(false, "Credentials do not allow login from your current IP address.", null);
CurrentPrincipal = new CodeworksPrincipal<T>(userName, userProvider.GetRoles(user), user);
// remember to change CookieParameterCount if you change parameter count here
string cookieData = String.Format("{0}|{1}|{2}", CurrentIdentity.Name, customer, CurrentPrincipal.AllRoles);
persistenceProvider.SetAuthCookie(1, userName, DateTime.Now.AddMonths(1), persistent, cookieData);
// TODO create an audit log entry for the current request
return new AuthenticationResult(true, null, null);
}
private AuthenticationResult ValidateInput(string login, string password)
{
var result = new AuthenticationResult(true, "Invalid or missing credentials.");
if(String.IsNullOrEmpty(login))
{
result.Success = false;
result.Errors.Add("login", "You must specify an alias or email address.");
}
if(String.IsNullOrEmpty(password))
{
result.Success = false;
result.Errors.Add("password", "You must specify a password.");
}
// TODO add message to inform users of other requirements.
return result;
}
#endregion
#region Cookie Authentication
public void CookieAuthenticate(string visitorAddress)
{
HttpCookie cookie = persistenceProvider.GetAuthCookie();
if(cookie != null)
{
string userName;
string userData = persistenceProvider.GetAuthCookieValue(out userName);
string[] cookieData = userData.Split('|');
// extract data from cookie
bool isValid = cookieData.Length == CookieParameterCount &&
! string.IsNullOrEmpty(cookieData[ 0 ]) &&
cookieData[ 0 ] == userName &&
IsAuthorizedVisitor(cookieData[ 1 ], cookieData[ 0 ], visitorAddress);
if(isValid)
{
string customer = cookieData[ 1 ];
string[] roles = cookieData[ 2 ].Split(',');
T user = userProvider.GetUser(customer, userName);
CurrentPrincipal = new CodeworksPrincipal<T>(userName, roles, user);
}
}
}
#endregion
#region Logout
public void Logout()
{
// logout the current user
if(HttpContext.Current.Request.IsAuthenticated || CurrentPrincipal != null)
{
long address = GetAddressFromString(HttpContext.Request.UserHostAddress);
// TODO add audit log entry
// sign out current user
persistenceProvider.RemoveAuthCookie();
CurrentPrincipal = null;
}
}
#endregion
#region VisitorAddress Checks
public long GetAddressFromString(string address)
{
IPAddress ipAddress;
if(IPAddress.TryParse(address, out ipAddress))
{
byte[] segments = ipAddress.GetAddressBytes();
long result = 0;
for(int i = 0; i < segments.Length; i++)
{
result += segments[ i ] << (i * 8);
}
return result;
}
return long.MaxValue;
}
public bool IsAuthorizedVisitor(string customer, string userName, string visitorAddress)
{
return IsAuthorizedVisitor(customer, userName, GetAddressFromString(visitorAddress));
}
public bool IsAuthorizedVisitor(string customer, string userName, long visitorAddress)
{
T user = userProvider.GetUser(customer, userName);
return IsAuthorizedVisitor(user, visitorAddress);
}
public bool IsAuthorizedVisitor(T user, string visitorAddress)
{
return IsAuthorizedVisitor(user, GetAddressFromString(visitorAddress));
}
public bool IsAuthorizedVisitor(T user, long visitorAddress)
{
if(user == null || visitorAddress == 0)
return false;
if(user.Hosts.Count == 0)
return true;
foreach(Host host in user.Hosts)
{
if(IsAuthorizedVisitor(host.HostAddress, host.HostMask, visitorAddress))
return true;
}
return true;
}
public bool IsAuthorizedVisitor(long allowedAddress, long allowedMask, long visitorAddress)
{
long requireMask = allowedAddress & allowedMask;
return (visitorAddress & requireMask) == requireMask;
}
#endregion
#region Cryptographic Helpers
public static string GetCryptographicHash(string password)
{
SHA256 hash = SHA256.Create();
byte[] input = Encoding.UTF8.GetBytes(password);
byte[] output = hash.ComputeHash(input);
return Convert.ToBase64String(output);
}
#endregion
}
Vous pouvez dépouiller les bits pour vérifier l'hôte des visiteurs adresse si vous n'en avez pas besoin. J'espère que cela aidera même si ce n'est pas un fournisseur d'adhésion en soi ;-)
- 1. TelerikProfileProvider avec un fournisseur d'appartenances personnalisées
- 2. Où trouver un examen rapide de Java et/ou C++?
- 3. Délai d'expiration du fournisseur d'appartenances personnalisées dans asp.net 4.0
- 4. Injection de dépendances avec fournisseur d'appartenances personnalisées
- 5. Contrôle de connexion et fournisseur d'appartenances personnalisées
- 6. Où puis-je trouver une référence rapide pour Basic Basic?
- 7. Regroupement de rôles dans un fournisseur d'appartenances personnalisées dans ASP.Net MVC 2
- 8. Où stocker des classes personnalisées dans ASP.NET MVC?
- 9. Fournisseur d'appartenances asp.net personnalisé
- 10. Où puis-je trouver un simple tutoriel ASP.NET MVC (C#)?
- 11. Où mettre des données personnalisées
- 12. Fournisseur de rôle ASP.NET vs fournisseur d'appartenance
- 13. Où trouver Microsoft.Web.Mvc.dll
- 14. Où trouver Rhino Commons
- 15. Fournisseur d'appartenance ASP.NET MVC
- 16. Authentification et fournisseur ASP.NET
- 17. ASP.NET SqlMembership Fournisseur évolutivité
- 18. Fournisseur d'appartenance ASP.NET
- 19. asp.net mvc - fournisseur d'appartenances
- 20. Fournisseur d'appartenances ASP.NET personnalisé - Ajouter un utilisateur à des rôles
- 21. abonnement asp.net sélectionner fournisseur
- 22. ASP.net Erreurs personnalisées Loggin
- 23. asp.net mvc fournisseur d'appartenances personnalisées - strict login cache à une application
- 24. Erreurs personnalisées ASP.NET ignorées
- 25. Générique et fournisseur d'appartenance ASP.Net
- 26. Fournisseur d'appartenance ASP.NET Active Directory et fournisseur de profils SQL
- 27. Fournisseur d'appartenances ASP.NET MVC "CreateUser"
- 28. Intégration du fournisseur d'appartenances personnalisées dans la solution existante
- 29. Verrouillage d'un utilisateur dans un fournisseur d'appartenance ASP.Net personnalisé
- 30. Erreurs personnalisées pour les dossiers "App"? (ASP.NET)
Mais je vais laisser la question ouverte puisque j'ai aussi besoin d'aide pour la connectivité de base de données. Merci – Luke101
Vous devriez poser une question distincte pour cela, car ce n'est pas vraiment lié à l'authentification. Vous n'avez besoin que des méthodes de base de données pour implémenter l'interface ISecurityUserProvider. –