Какой провайдер членства реализует пользователей, хранящихся в web.config?

Наличие момента слепого кода.

ASP.NET 4.0.

Web.config:

<?xml version="1.0"?>
<configuration>
  <system.web>
    <authentication mode="Forms">
      <forms name="DataViewer" loginUrl="login.aspx">
        <credentials passwordFormat="Clear">
          <user name="devuser" password="test" />
        </credentials>
      </forms>
    </authentication>
    <authorization>
      <deny users="?" />
    </authorization>
  </system.web>

и элемент управления входами:

  <asp:Login ID="login" runat="server" />

Если я введу имя пользователя и пароль и нажмите "Войти", он зависает.

Если я сломаюсь, я вижу в стеке вызовов, что login.AuthenticateUsingMembershipProvider() находится в середине вызова SqlMembershipProvider.ValidateUser(). База данных не определена или вообще не участвует в этом проекте, и я не указал, что следует использовать SqlMembershipProvider.

Итак, мой вопрос: какой член провайдера должен использовать, чтобы ASP.NET использовал имена пользователей и пароли в элементе <credentials> web.config?

Ответ 1

Я удивлен, что, учитывая, как дизайнеры фреймворков столкнулись с проблемой определения элемента <credentials />, что они не реализовали какой-либо код для его использования.

Я нашел своеобразную рабочую реализацию этого здесь, который я исправил и включил ниже. Все остальные члены MembershipProvider throw NotImplementedException.

using System.Configuration;
using System.Web.Configuration;
using System.Web.Security;

public class WebConfigMembershipProvider : MembershipProvider
{
    private FormsAuthenticationUserCollection _users = null;
    private FormsAuthPasswordFormat _passwordFormat;

    public override void Initialize(string name,
      System.Collections.Specialized.NameValueCollection config)
    {
        base.Initialize(name, config);
        _passwordFormat = getPasswordFormat();
    }

    public override bool ValidateUser(string username, string password)
    {
        var user = getUsers()[username];
        if (user == null) return false;

        if (_passwordFormat == FormsAuthPasswordFormat.Clear)
        {
            if (user.Password == password)
            {
                return true;
            }
        }
        else
        {
            if (user.Password == FormsAuthentication.HashPasswordForStoringInConfigFile(password,
                _passwordFormat.ToString()))
            {
                return true;
            }
        }

        return false;
    }

    protected FormsAuthenticationUserCollection getUsers()
    {
        if (_users == null)
        {
            AuthenticationSection section = getAuthenticationSection();
            FormsAuthenticationCredentials creds = section.Forms.Credentials;
            _users = section.Forms.Credentials.Users;
        }
        return _users;
    }

    protected AuthenticationSection getAuthenticationSection()
    {
        Configuration config = WebConfigurationManager.OpenWebConfiguration("~");
        return (AuthenticationSection)config.GetSection("system.web/authentication");
    }

    protected FormsAuthPasswordFormat getPasswordFormat()
    {
        return getAuthenticationSection().Forms.Credentials.PasswordFormat;
    }
}

Ответ 2

Вам понадобится написать для этого своего провайдера. Это должно быть относительно просто взять образец ReadOnlyXmlMembershipProvider в документации MSDN и изменить его, чтобы читать пользователей и учетные данные из web.config, а не внешний XML файл.

Ответ 3

Я не уверен, что вы пробовали, но...

FormsAuthentication.Authenticate отвечает за это для вас (хотя он устарел сейчас, потому что рекомендуемое поведение заключается в использовании объекта Membership )

Из MSDN:

Метод Authenticate проверяет учетные данные пользователя, которые хранятся в разделе учетных данных файла конфигурации приложения. Кроме того, вы можете использовать членство ASP.NET для хранения учетных данных пользователя и вызвать ValidateUser для проверки учетных данных.

Вы также можете удалить поставщиков членства (потому что даже если вы не объявляете их в своем web.config, они наследуются от файла machine.config)

  <membership>
    <providers>
      <remove name="AspNetSqlMembershipProvider"/>
    </providers>
  </membership>