Sie können implementieren jeden Methoden, die Sie auf Ihrem benutzerdefinierten Anbieter zu wollen, und in Ihrem Fall es Macht Sinn so und nur werfen Mitgliedschaft auf Ihre Art zu tun, bevor Sie.
Aber das Brechen der Schnittstelle, um einige einfache Out-of-Band-Informationen zu bekommen, kann in der Zukunft wieder beißen. Es gibt andere Möglichkeiten, dies zu tun und die Provider-API zu erhalten und Ihre zukünftigen Optionen offen zu halten.
In der Vergangenheit habe ich ein Cookie verwendet, um Out-of-Band-Informationen wie diese von einem Anbieter an den Verbraucher zu übergeben.
Der HttpContext.Current ist für den Anbieter derselbe wie für die Seite, so dass ein Cookie, der in dem Anbieter festgelegt wird, in dem Consumer gelesen werden kann.
Stellen Sie einfach sicher, dass Sie den Cookie nach dem Aufruf Ihres Providers entfernen. Das Erstellen eines temporären Cookies hilft Fehler zu minimieren, aber entfernen Sie es trotzdem aus der Sammlung.
Hier ist ein Arbeitsbeispiel.
CookieChannelMembershipProvider
using System;
using System.Web;
using System.Web.Security;
namespace CookieChannel
{
public class CookieChannelMembershipProvider : MembershipProvider
{
public override bool ValidateUser(string username, string password)
{
if(username=="asshat")
{
HttpContext.Current.Request.Cookies.Add(new HttpCookie("__cookiechannel", "user is an asshat. do not let him in."));
return false;
}
return true;
}
#region Not implemented
public override bool EnablePasswordRetrieval
{
get { throw new NotImplementedException(); }
}
public override bool EnablePasswordReset
{
get { throw new NotImplementedException(); }
}
public override bool RequiresQuestionAndAnswer
{
get { throw new NotImplementedException(); }
}
public override string ApplicationName
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
public override int MaxInvalidPasswordAttempts
{
get { throw new NotImplementedException(); }
}
public override int PasswordAttemptWindow
{
get { throw new NotImplementedException(); }
}
public override bool RequiresUniqueEmail
{
get { throw new NotImplementedException(); }
}
public override MembershipPasswordFormat PasswordFormat
{
get { throw new NotImplementedException(); }
}
public override int MinRequiredPasswordLength
{
get { throw new NotImplementedException(); }
}
public override int MinRequiredNonAlphanumericCharacters
{
get { throw new NotImplementedException(); }
}
public override string PasswordStrengthRegularExpression
{
get { 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 ChangePasswordQuestionAndAnswer(string username, string password,
string newPasswordQuestion, string newPasswordAnswer)
{
throw new NotImplementedException();
}
public override string GetPassword(string username, string answer)
{
throw new NotImplementedException();
}
public override bool ChangePassword(string username, string oldPassword, string newPassword)
{
throw new NotImplementedException();
}
public override string ResetPassword(string username, string answer)
{
throw new NotImplementedException();
}
public override void UpdateUser(MembershipUser user)
{
throw new NotImplementedException();
}
public override bool UnlockUser(string userName)
{
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();
}
public override bool DeleteUser(string username, bool deleteAllRelatedData)
{
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 MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize,
out int totalRecords)
{
throw new NotImplementedException();
}
public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize,
out int totalRecords)
{
throw new NotImplementedException();
}
#endregion
}
}
Web.config
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true"/>
<authentication mode="Windows" />
<membership defaultProvider="cookieChannelProvider" userIsOnlineTimeWindow="15">
<providers>
<add
name="cookieChannelProvider"
type="CookieChannel.CookieChannelMembershipProvider, CookieChannel"
connectionStringName="none"
enablePasswordRetrieval="true"
enablePasswordReset="true"
requiresQuestionAndAnswer="true"
/>
</providers>
</membership>
</system.web>
</configuration>
Standard.aspx
<%@ Page Language="C#" %>
<script runat="server">
protected void Button1_Click(object sender, EventArgs e)
{
ValidateUser("user", "user");
}
protected void Button2_Click(object sender, EventArgs e)
{
ValidateUser("asshat", "asshat");
}
private void ValidateUser(string username, string password)
{
bool validated = Membership.ValidateUser(username, password);
string message = validated.ToString();
if (Request.Cookies["__cookiechannel"] != null)
{
message += ":" + Request.Cookies["__cookiechannel"].Value;
Request.Cookies.Remove("__cookiechannel");
}
Label1.Text = message;
}
</script>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Button ID="Button1" runat="server" onclick="Button1_Click"
Text="Validate Valued User" />
<asp:Button ID="Button2" runat="server" onclick="Button2_Click"
Text="Validate Asshat User" />
</div>
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
</form>
</body>
</html>
Es ist keine gute Idee, eine Aussperrung auf einer Web-basierte Anwendung zu berichten, jemand eine Brute-Force-Attacke versucht, wissen eher zu stoppen und zu warten, als die Ausübung und möglicherweise das richtige Passwort präsentieren zu ein gesperrtes Konto und damit keinen Zugang. Nur ein Gedanke für dich. – Lazarus
Danke für diesen Hinweis Lazarus. – Cosmo
Dies ist ein Mangel des MembershipProvider. ValidateUser() gibt nur ein Bool zurück, was Sie mit BAD-Optionen belässt. 1) requery die Datenbank für weitere Informationen (Overhead), 2) Methoden hinzufügen und Ihren Provider (die Unabhängigkeit brechen), oder 3) eine Out-of-Band-Cookie-Operation. MS sollte den Anbieter aktualisieren. Es wäre großartig, wenn ValidateUser mindestens zurückliefert und AuthenticationStatuts enumeriert, ähnlich wie CreateUser() eine MembershipCreateStatus-Enumeration zurückgibt. Obwohl ich etwas mehr sehen möchte, da selbst die MembershipCreateStatus-Enumeration begrenzt ist (http://forums.asp.net/t/1521981.aspx). – EBarr