SqlMembershipProvider где IIS и SQL находятся на разных машинах? - PullRequest
0 голосов
/ 11 марта 2010

Мы переводим один из моих сайтов в производство. Из-за того, что брандмауэр и веб-сайт и база данных находятся на разных компьютерах, веб-сайт не может напрямую подключиться к серверу SQL. Мы настроили это так, что мы выполняем весь доступ к базе данных через службу WCF. Все это прекрасно работает.

Проблема, однако, я обнаружил, заключается в AspNetSqlProvider. Я не слишком знаком с поставщиками, за исключением того, что настраиваю его для вашего сайта, но из того, что я собираю, вы передаете объекту провайдера строку подключения, и он автоматически обрабатывает учетные записи ASP.NET для вашего сайта. У меня не может быть этого на производстве, однако, как я уже говорил, веб-сайт и база данных не могут видеть друг друга, и автоматическое связывание IIS и базы данных не будет работать.

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

Как настроить AspNetSqlProvider, когда IIS и база данных находятся на разных компьютерах? Есть ли способ запустить AspNetSqlProvider через службу wcf или другой объект, чтобы он не подключался напрямую к серверу SQL?

Заранее спасибо!

1 Ответ

1 голос
/ 30 апреля 2010

Вы можете обернуть собственного провайдера членства вокруг этой услуги. Что-то, о чем нужно помнить, - это защита конечной точки! БЕЗОПАСНОСТЬ КОНЦЕПЦИИ!

Используйте сертификаты или AD или что-то еще И SSL , так как вы будете передавать учетные данные пользователей по сети.

Я не тестировал каждый метод в этом классе, но предыдущие реализации работали просто отлично, так что, возможно, в конечном итоге вы попадете туда, куда вам нужно.

ОБЕСПЕЧИВАЙТЕ КОНЕЦ!

// <copyright project="Salient.ScriptModel" file="MembershipService.svc" company="Sky Sanders">
// http://skysanders.net/subtext
// Attribution is appreciated
// </copyright>
// <version>1.0</version>
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.Web.Security;

namespace Salient.ScriptModel
{
    [ServiceContract(Namespace = "Salient.ScriptModel", Name = "MembershipProvider")]
    public interface IMembershipProvider
    {
        string ProviderName { get; set; }

        [OperationContract]
        DateTime TestInput(DateTime date);

        [OperationContract]
        ProviderProperties GetProviderProperties();

        [OperationContract]
        MembershipUser GetUserByKey(object providerUserKey, bool userIsOnline);

        [OperationContract]
        MembershipCreateResult CreateUser(string username, string password,
                                          string email, string passwordQuestion,
                                          string passwordAnswer, bool isApproved,
                                          object providerUserKey);

        [OperationContract]
        MembershipCreateResult AddUser(MembershipUser user);

        [OperationContract]
        bool ChangePasswordQuestionAndAnswer(string username, string password,
                                             string newPasswordQuestion, string newPasswordAnswer);

        [OperationContract]
        string GetPassword(string username, string answer);

        [OperationContract]
        bool ChangePassword(string username, string oldPassword, string newPassword);

        [OperationContract]
        string ResetPassword(string username, string answer);

        [OperationContract]
        void UpdateUser(MembershipUser user);

        [OperationContract]
        bool ValidateUser(string username, string password);

        [OperationContract]
        bool UnlockUser(string userName);

        [OperationContract]
        MembershipUser GetUserByName(string username, bool userIsOnline);

        [OperationContract]
        string GetUserNameByEmail(string email);

        [OperationContract]
        bool DeleteUser(string username, bool deleteAllRelatedData);

        [OperationContract]
        MembershipFindResult GetAllUsers(int pageIndex, int pageSize);

        [OperationContract]
        int GetNumberOfUsersOnline();

        [OperationContract]
        MembershipFindResult FindUsersByName(string usernameToMatch, int pageIndex,
                                             int pageSize);

        [OperationContract]
        MembershipFindResult FindUsersByEmail(string emailToMatch, int pageIndex,
                                              int pageSize);
    }

    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class MembershipProvider : IMembershipProvider
    {
        private System.Web.Security.MembershipProvider Provider
        {
            get
            {
                if (string.IsNullOrEmpty(ProviderName))
                {
                    return Membership.Provider;
                }
                return Membership.Providers[ProviderName];
            }
        }

        #region IMembershipProvider Members

        public DateTime TestInput(DateTime date)
        {
            return date;
        }

        public string ProviderName { get; set; }

        public ProviderProperties GetProviderProperties()
        {
            var returnValue = new ProviderProperties
                                  {
                                      ApplicationName = Provider.ApplicationName,
                                      EnablePasswordReset = Provider.EnablePasswordReset,
                                      EnablePasswordRetrieval = Provider.EnablePasswordRetrieval,
                                      MaxInvalidPasswordAttempts = Provider.MaxInvalidPasswordAttempts,
                                      MinRequiredNonAlphanumericCharacters =
                                          Provider.MinRequiredNonAlphanumericCharacters,
                                      MinRequiredPasswordLength = Provider.MinRequiredPasswordLength,
                                      PasswordAttemptWindow = Provider.PasswordAttemptWindow,
                                      PasswordFormat = Provider.PasswordFormat,
                                      PasswordStrengthRegularExpression = Provider.PasswordStrengthRegularExpression,
                                      RequiresQuestionAndAnswer = Provider.RequiresQuestionAndAnswer,
                                      RequiresUniqueEmail = Provider.RequiresUniqueEmail
                                  };
            return returnValue;
        }

        public MembershipUser GetUserByKey(object providerUserKey, bool userIsOnline)
        {
            return Provider.GetUser(providerUserKey, userIsOnline);
        }

        public MembershipCreateResult CreateUser(string username, string password,
                                                 string email, string passwordQuestion,
                                                 string passwordAnswer, bool isApproved,
                                                 object providerUserKey)
        {
            MembershipCreateStatus status;
            MembershipUser user = Provider.CreateUser(username, password, email, passwordQuestion, passwordAnswer,
                                                      isApproved,
                                                      providerUserKey, out status);
            return new MembershipCreateResult(user, status);
        }

        public MembershipCreateResult AddUser(MembershipUser user)
        {
            return new MembershipCreateResult(user, MembershipCreateStatus.DuplicateEmail);
        }

        public bool ChangePasswordQuestionAndAnswer(string username, string password,
                                                    string newPasswordQuestion, string newPasswordAnswer)
        {
            return Provider.ChangePasswordQuestionAndAnswer(username, password, newPasswordQuestion, newPasswordAnswer);
        }

        public string GetPassword(string username, string answer)
        {
            return Provider.GetPassword(username, answer);
        }

        public bool ChangePassword(string username, string oldPassword, string newPassword)
        {
            return Provider.ChangePassword(username, oldPassword, newPassword);
        }

        public string ResetPassword(string username, string answer)
        {
            return Provider.ResetPassword(username, answer);
        }

        public void UpdateUser(MembershipUser user)
        {
            Provider.UpdateUser(user);
        }

        public bool ValidateUser(string username, string password)
        {
            return Provider.ValidateUser(username, password);
        }

        public bool UnlockUser(string userName)
        {
            return Provider.UnlockUser(userName);
        }

        public MembershipUser GetUserByName(string username, bool userIsOnline)
        {
            return Provider.GetUser(username, userIsOnline);
        }

        public string GetUserNameByEmail(string email)
        {
            return Provider.GetUserNameByEmail(email);
        }

        public bool DeleteUser(string username, bool deleteAllRelatedData)
        {
            return Provider.DeleteUser(username, deleteAllRelatedData);
        }

        public MembershipFindResult GetAllUsers(int pageIndex, int pageSize)
        {
            int totalRecords;
            MembershipUserCollection users = Provider.GetAllUsers(pageIndex, pageSize, out totalRecords);
            var list = new List<MembershipUser>();
            foreach (MembershipUser user in users)
            {
                list.Add(user);
            }
            return new MembershipFindResult(list, totalRecords);
        }

        public int GetNumberOfUsersOnline()
        {
            return Provider.GetNumberOfUsersOnline();
        }

        public MembershipFindResult FindUsersByName(string usernameToMatch, int pageIndex,
                                                    int pageSize)
        {
            int totalRecords;
            MembershipUserCollection users = Provider.FindUsersByName(usernameToMatch, pageIndex, pageSize,
                                                                      out totalRecords);
            var list = new List<MembershipUser>();
            foreach (MembershipUser user in users)
            {
                list.Add(user);
            }
            return new MembershipFindResult(list, totalRecords);
        }

        public MembershipFindResult FindUsersByEmail(string emailToMatch, int pageIndex,
                                                     int pageSize)
        {
            int totalRecords;
            MembershipUserCollection users = Provider.FindUsersByEmail(emailToMatch, pageIndex, pageSize,
                                                                       out totalRecords);
            var list = new List<MembershipUser>();
            foreach (MembershipUser user in users)
            {
                list.Add(user);
            }
            return new MembershipFindResult(list, totalRecords);
        }

        #endregion
    }

    [DataContract]
    public class MembershipFindResult
    {
        [DataMember] public int RecordCount;
        [DataMember] public IEnumerable<MembershipUser> Users;

        public MembershipFindResult()
        {
        }

        public MembershipFindResult(IEnumerable<MembershipUser> users, int recordCount)
        {
            Users = users;
            RecordCount = recordCount;
        }
    }

    [DataContract]
    public class MembershipCreateResult
    {
        [DataMember] public MembershipCreateStatus CreateStatus;
        [DataMember] public MembershipUser User;

        public MembershipCreateResult()
        {
        }

        public MembershipCreateResult(MembershipUser user, MembershipCreateStatus createStatus)
        {
            User = user;
            CreateStatus = createStatus;
        }
    }

    [DataContract]
    public class ProviderProperties
    {
        public ProviderProperties()
        {
        }

        public ProviderProperties(bool enablePasswordRetrieval, bool enablePasswordReset, bool requiresQuestionAndAnswer,
                                  int maxInvalidPasswordAttempts,
                                  int passwordAttemptWindow, bool requiresUniqueEmail,
                                  MembershipPasswordFormat passwordFormat, int minRequiredPasswordLength,
                                  int minRequiredNonAlphanumericCharacters,
                                  string passwordStrengthRegularExpression, string applicationName)
        {
            EnablePasswordRetrieval = enablePasswordRetrieval;
            EnablePasswordReset = enablePasswordReset;
            RequiresQuestionAndAnswer = requiresQuestionAndAnswer;
            MaxInvalidPasswordAttempts = maxInvalidPasswordAttempts;
            PasswordAttemptWindow = passwordAttemptWindow;
            RequiresUniqueEmail = requiresUniqueEmail;
            PasswordFormat = passwordFormat;
            MinRequiredPasswordLength = minRequiredPasswordLength;
            MinRequiredNonAlphanumericCharacters = minRequiredNonAlphanumericCharacters;
            PasswordStrengthRegularExpression = passwordStrengthRegularExpression;
            ApplicationName = applicationName;
        }

        [DataMember]
        public bool EnablePasswordRetrieval { get; set; }

        [DataMember]
        public bool EnablePasswordReset { get; set; }

        [DataMember]
        public bool RequiresQuestionAndAnswer { get; set; }

        [DataMember]
        public int MaxInvalidPasswordAttempts { get; set; }

        [DataMember]
        public int PasswordAttemptWindow { get; set; }

        [DataMember]
        public bool RequiresUniqueEmail { get; set; }

        [DataMember]
        public MembershipPasswordFormat PasswordFormat { get; set; }

        [DataMember]
        public int MinRequiredPasswordLength { get; set; }

        [DataMember]
        public int MinRequiredNonAlphanumericCharacters { get; set; }

        [DataMember]
        public string PasswordStrengthRegularExpression { get; set; }

        [DataMember]
        public string ApplicationName { get; set; }
    }

}

РЕДАКТИРОВАТЬ: пришлось удалить комментарии, чтобы соответствовать.

p.s. БЕЗОПАСНОСТЬ В ЭТОМ РАЗРЕШЕНИИ!

...