MVC3 Custom MembershipProvider & Active Directory - PullRequest
3 голосов
/ 15 января 2012

У меня есть приложение MVC3, у которого есть пользовательский поставщик членства и пользователь / роли, которые хранятся в базе данных. Пользователи создаются вручную в приложении по мере необходимости и назначаются соответствующие роли.

Я хотел бы теперь расширить приложение, чтобы обеспечить возможность использования Active Directory, хотя, поскольку приложение имеет несколько настраиваемых полей + таблицы с поиском FK для пользователя, я думаю, что мне все равно придется иметь настраиваемый версия поставщика членства в активном каталоге по умолчанию.

Кто-нибудь в SF делал что-то подобное, чем они могут поделиться со мной? Спасибо

1 Ответ

0 голосов
/ 20 декабря 2012

Я знаю, что это старый вопрос, но ...

Посмотрим, с чего начать

В моем веб-приложении я настроил федеративную проверку подлинности на основе утверждений непосредственно с моего сервера ADFS. Я не смог найти хороший учебник о том, как это сделать, потому что это не тривиально. Но есть много упоминаний о том, как сделать это с помощью лазурной ACS в качестве посредника. Этот, по крайней мере, поможет вам начать:

http://haishibai.blogspot.com/2011/05/tutorialaspnet-mvc-3-claim-based.html

Как только вы это заработаете, вам просто понадобится пара вещей.

Добавьте пару свойств в вашу пользовательскую таблицу базы данных, которые вы можете связать с AD. Я храню AD GUID в моем, но я также использую адрес электронной почты в качестве дополнительного. Это позволяет мне создавать пользователей в моем приложении, а затем проверять их подлинность с помощью AD. Я просто передаю их электронную почту в качестве претензии, сопоставляю их с пользователем в моем приложении, а затем добавляю AD GUID для пользователя.

Я также использую наследование для своей аутентификации. Все мои контроллеры наследуются от BaseController, поэтому они получают это стандартное поведение.

public class BaseController
{
    protected override void OnAuthorization(System.Web.Mvc.AuthorizationContext filterContext)
    {
        if (filterContext.HttpContext.User.Identity.IsAuthenticated)
        {
            //read in the claims that we got back from ADFS
            IClaimsPrincipal icp = Thread.CurrentPrincipal as IClaimsPrincipal;
            IClaimsIdentity ici = icp.Identity as IClaimsIdentity;

            var claims = ici.Claims;

            // This is a claim that I add manually to see if I've already synced
            // ADFS user with DB user
            var ppid = claims.FirstOrDefault(x => x.ClaimType == ClaimTypes.PPID);
            if (ppid == null)
            {
                //query/sync user.
                var guidString = claims.FirstOrDefault(x => x.ClaimType == ClaimTypes.Name).Value;

                // get AD GUID 
                var userGuid = new Guid(System.Convert.FromBase64String(guidString));

                //look up user
                var currentUser = UserRepository.FetchUserByGUID(userGuid);

                //if user not found try fetch by email.
                if (currentUser == null)
                {
                    var email = claims.FirstOrDefault(x => x.ClaimType == ClaimTypes.Email).Value;
                    currentUser = UserRepository.FetchByEmail(email);
                }

                //If user is still not found create User
                if (currentUser == null)
                {
                    currentUser = new Models.User();
                    BaseRepository.GetDataContext().Users.Add(currentUser);
                }

                //update users information using AD claim as master record
                currentUser.ADID = userGuid;
                currentUser.Name = claims.FirstOrDefault(x => x.ClaimType == ClaimTypes.GivenName).Value;
                currentUser.EmailAddress = claims.FirstOrDefault(x => x.ClaimType == ClaimTypes.Email).Value;
                currentUser.LastLoginDate = DateTime.UtcNow;
                currentUser.LoginCount = currentUser.LoginCount + 1;

                BaseRepository.GetDataContext().SaveChanges();

                // Now that you have your AD user linked to your user record 
                // in your database...
                // Create new claims in your ADFS token that include all the roles that
                // your user has.  That way you can just piggyback on claims based 
                // authentication
                foreach (var r in currentUser.Roles)
                {
                    claims.Add(new Claim(ClaimTypes.Role, r.Name));
                }

                // Add userid claim so that we know that this users claims have already
                // been sync with my database
                claims.Add(new Claim(ClaimTypes.PPID, currentUser.Id.ToString()));
            }
        }

        base.OnAuthorization(filterContext);
    }

Надеюсь, это поможет!

...