Изменение методов UserManagerExtensions System.Security.Principal.WindowsIdentity

Мы используем Identity 2 с MVC 5 для нашего веб-проекта. Требуется уметь настраивать олицетворенного пользователя для веб-приложения в web.config следующим образом

<system.web>
  <identity impersonate="true" userName="domain\impersonated" password="password" />
</system.web>

Мы реализовали пользовательский UserManager и настроили аутентификацию следующим образом:

public partial class Startup
{
    public void ConfigureAuth(IAppBuilder app)
    {
        app.CreatePerOwinContext(MyIdentityContext.Create);
        app.CreatePerOwinContext<MyUserManager>(MyUserManager.Create);
        app.CreatePerOwinContext<MySignInManager>(MySignInManager.Create);

        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/Account/Login"),
            Provider = new CookieAuthenticationProvider
            {
                // Enables the application to validate the security stamp when the user logs in.
                // This is a security feature which is used when you change a password or add an external login to your account.  
                OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<MyUserManager, MyUser, Guid>(
                    validateInterval: TimeSpan.FromMinutes(30),
                    regenerateIdentityCallback: (manager, user) => user.GenerateUserIdentityAsync(manager),
                    getUserIdCallback: (claimsIdentity) => (Guid.Parse(claimsIdentity.GetUserId()))),
            },
            ExpireTimeSpan = TimeSpan.FromMinutes(settingsFacade.GetSessionTimeout())
        });
    }
}

Мы также реализовали пользовательский UserStore, взаимодействуя с базой данных с помощью EF. Строка подключения настроена на использование Integrated Security=True для использования нашего олицетворенного пользователя для доступа к базе данных.

Мы реализовали AccountController с действием ChangePassword

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult ChangePassword(ChangePasswordViewModel model)
{
    if (!ModelState.IsValid)
    {
       return View(model);
    }

    var userGuid = User.Identity.GetUserGuid();
    var result = UserManager.ChangePassword(userGuid, model.OldPassword, model.NewPassword);

    if (result.Succeeded)
    {
        var user = UserManager.FindById(User.Identity.GetUserGuid());
        if (user != null)
        {
            SignInManager.SignIn(user, isPersistent: false, rememberBrowser: false);
        }
        return RedirectToAction("Index", new { Message = AccountMessageId.ChangePasswordSuccess });
    }

    AddErrors(result);

    return View(model);
}

Когда вызывается действие ChangePassword, оно запускается от имени другого пользователя, как и ожидалось. Когда я останавливаюсь на точке останова внутри ChangePassword

System.Security.Principal.WindowsIdentity.GetCurrent().Name = "domain\impersonated"

Когда я захожу в UserManager.ChangePassword и останавливаю отладчик в нашей общедоступной задаче UserStore FindByIdAsync(Guid userId), WindowsIdentity заменяется на пользовательский пул приложений, а не на олицетворенного пользователя. Пользователь приложения не имеет доступа к базе данных. Мы хотим, чтобы только олицетворенный пользователь имел доступ к базе данных.

System.Security.Principal.WindowsIdentity.GetCurrent().Name = "domain\appPoolUser"

Я заметил, когда я заменяю вызов метода синхронизации расширения

UserManager.ChangePassword(userGuid, model.OldPassword, model.NewPassword);

с вызовом метода asych

UserManager.ChangePasswordAsync(userGuid, model.OldPassword, model.NewPassword).Result;

WindowsIdentity не изменяется, и FindByIdAsync работает в олицетворенном пользовательском контексте.

Что мы делаем не так? Почему методы синхронизации и асинхронности ведут себя по-разному. Есть ли какая-либо конфигурация OWIN, которую мы пропускаем, для правильной работы с олицетворением? Спасибо.

0 ответов

Другие вопросы по тегам