ASP.NET Core Identity с проверкой подлинности Windows - PullRequest
0 голосов
/ 03 июля 2019

Я использую .NET Core 3.0 Preview6.
У нас есть приложение для интрасети с включенной аутентификацией Windows, что означает, что только действительные пользователи AD могут использовать приложение.
Однако нам нравится запускать собственный бэкэнд аутентификации с ASP.NET Identity, потому что он работает "из коробки". Я только что добавил столбец в таблицу AspNetUsers с именем пользователя Windows.

Чего я хотел бы добиться, так это чтобы пользователи Windows автоматически входили в приложение с помощью своей учетной записи Windows.
Я уже создал специальное промежуточное программное обеспечение для аутентификации, см. Код ниже:

public class AutoLoginMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ILogger _logger;

    public AutoLoginMiddleware(RequestDelegate next, ILogger<AutoLoginMiddleware> logger)
    {
        _next = next;
        _logger = logger;
    }

    public async Task InvokeAsync(HttpContext context, UserService userService, UserManager<IntranetUser> userManager, 
        SignInManager<IntranetUser> signInManager)
    {
        if (signInManager.IsSignedIn(context.User))
        {
            _logger.LogInformation("User already signed in");
        }
        else
        {
            if (context.User.Identity as WindowsIdentity != null)
            {
                _logger.LogInformation($"User with Windows Login {context.User.Identity.Name} needs to sign in");
                var windowsLogin = context.User.Identity.Name;


                var user = await userManager.Users.FirstOrDefaultAsync(u => u.NormalizedWindowsLogin == windowsLogin.ToUpperInvariant());

                if (user != null)
                {
                    await signInManager.SignInAsync(user, true, "automatic");
                    _logger.LogInformation($"User with id {user.Id}, name {user.UserName} successfully signed in");

                    // Workaround
                    context.Items["IntranetUser"] = user;
                }
                else
                {
                    _logger.LogInformation($"User cannot be found in identity store.");
                    throw new System.InvalidOperationException($"user not found.");
                }
            }
        }

        // Pass the request to the next middleware
        await _next(context);
    }
}

Док говорит, что SignInManager.SignInAsync создает новый ClaimsIdentity - но, похоже, этого не происходит - HttpContext.User всегда остается WindowsIdentity. При каждом повторном входе пользователя в систему вызов signInManager.IsSignedIn() всегда возвращает значение false.

Мой вопрос сейчас: это вообще хорошая идея иметь автоматическую аутентификацию таким образом? Какие еще способы существуют?

Мое следующее требование - иметь пользовательский AuthorizationHandler. Проблема здесь в том, что иногда в методе HandleRequirementAsync AuthorizationHandlerContext.User.Identity является WindowsIdentity, а затем вызов context.User.Identity.Name вызывает следующее исключение:

System.ObjectDisposedException: Safe handle has been closed.

Object name: 'SafeHandle'.

   at System.Runtime.InteropServices.SafeHandle.DangerousAddRef(Boolean& success)

   at System.StubHelpers.StubHelpers.SafeHandleAddRef(SafeHandle pHandle, Boolean& success)

   at Interop.Advapi32.GetTokenInformation(SafeAccessTokenHandle TokenHandle, UInt32 TokenInformationClass, SafeLocalAllocHandle TokenInformation, UInt32 TokenInformationLength, UInt32& ReturnLength)

   at System.Security.Principal.WindowsIdentity.GetTokenInformation(SafeAccessTokenHandle tokenHandle, TokenInformationClass tokenInformationClass, Boolean nullOnInvalidParam)

   at System.Security.Principal.WindowsIdentity.get_User()

   at System.Security.Principal.WindowsIdentity.<GetName>b__51_0()

   at System.Security.Principal.WindowsIdentity.<>c__DisplayClass67_0.<RunImpersonatedInternal>b__0(Object <p0>)

   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)

Теперь я предполагаю, что обе эти части не работают вместе. Иногда кажется, что есть проблема синхронизации - мой пользовательский AuthorizationHandler вызывается между вызовами на AutoLoginMiddleware

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...