Как исправить UserPrincipal, возвращающий пустую строку из вызова API - PullRequest
0 голосов
/ 09 января 2019

У меня есть приложение .net-core 2.2, работающее на Windows Server 2012 с использованием angular в качестве внешнего SPA. В домене Windows у меня установлена ​​встроенная проверка подлинности Windows, на сервере IIS у меня также есть сайт, работающий с аутентификацией Windows, основной проблемой, по-видимому, является учетная запись службы, на которой запущен AppPool, ЕСЛИ я запускаю сайт с моими учетными данными AD сайт возвращает имя пользователя и отображает его в угловом интерфейсе правильно, с

Добро пожаловать, Джон Смит

когда я запускаю AppPool с учетной записью службы, созданной нашей командой безопасности, сайт возвращает имя пользователя как

""

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

  1. Я использовал свою учетную запись AD для запуска AppPool, и сайт работает нормально. (это работает)
  2. Я запустил AppPool с учетной записью службы, и сайт неправильно возвращает UserPrincipal. (Пунктирная)
  3. Я подтвердил, что учетная запись службы может считывать данные в Active Directory, используя пользователей и группы AD в качестве учетной записи службы (это работает)

Контроллер API:

```


#region Get the logged in user
        [HttpGet("api/getLoggedInUserObject")] 
        public async Task<ActionResult> CheckForLoggedInUser()
        {
            try
            {
                var user = await userResolverSerivce.GetUserObject();

                return Ok(user);
            }
            catch (Exception ex)
            {
                Debug.Write(ex.InnerException.ToString());
                throw new Exception("User is not logged in");

            }

        }
        #endregion

```

Пользователь Prinicipal РЕПО

```

    public class UserResolver : IUserResolver
        {


            private AuthorizedGroups AuthorizedGroups { get; set; }
            private User _user { get; set; }


            public UserResolver(IOptions<AuthorizedGroups> authorizedGroups, User user)
            {
                AuthorizedGroups = authorizedGroups.Value;
                _user = user;

            }


            public Task<User> GetUserObject()
            {

                _user.FirstName = UserPrincipal.Current.GivenName;
                _user.LastName = UserPrincipal.Current.Surname;
                _user.FullName = $"{_user.FirstName} {_user.LastName}";
                _user.AuthorizedRoles = GetAuthorizedRoles();


                return Task.FromResult(_user);

            }

```

Угловой HTML:

```

    <div>
      <nav class="navbar-dark nav-bar-large bg-dark fixed-top">
        <span class="pull-right userHighlight">Welcome, {{data.userData.fullName}}</span>
        <div class="container" id="navbarNav">

          <img class="image-center" src="../../assets/img/logo_sm.png" />

        </div>
      </nav>
    </div>

```

Угловой TS:

```

    import { Component, OnInit, ViewEncapsulation } from '@angular/core';
    import { UserService } from '../services/user.service';
    import { User } from '../models/user';
    import { ActivatedRoute } from '@angular/router';

    @Component({
      selector: 'app-main-container',
      templateUrl: './main-container.component.html',
      styleUrls: ['./main-container.component.css'],
      encapsulation: ViewEncapsulation.None
    })
    export class MainContainerComponent implements OnInit {

      private data: any;
      private user: User[];

      constructor(private route: ActivatedRoute) { }

      ngOnInit() {
        this.data = this.route.snapshot.data;
        console.log(this.route.snapshot.data);
      }



    }

```

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

1 Ответ

0 голосов
/ 09 января 2019

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

Но основные API .Net не поддерживают олицетворение. Обходной путь - использовать приведенный ниже код для получения имени пользователя

Документация: https://docs.microsoft.com/en-us/aspnet/core/security/authentication/windowsauth?tabs=visual-studio&view=aspnetcore-2.2#impersonation

Ниже код может помочь вам:

app.Run(async (context) =>
{
    try
    {
        var user = (WindowsIdentity)context.User.Identity;

        await context.Response
            .WriteAsync($"User: {user.Name}\tState: {user.ImpersonationLevel}\n");

        WindowsIdentity.RunImpersonated(user.AccessToken, () =>
        {
            var impersonatedUser = WindowsIdentity.GetCurrent();
            var message =
                $"User: {impersonatedUser.Name}\t" +
                $"State: {impersonatedUser.ImpersonationLevel}";

            var bytes = Encoding.UTF8.GetBytes(message);
            context.Response.Body.Write(bytes, 0, bytes.Length);
        });
    }
    catch (Exception e)
    {
        await context.Response.WriteAsync(e.ToString());
    }
});
...