Аутентификация Windows в приложении Angular 2 и веб-API ASP.Net

Я пытаюсь реализовать аутентификацию Windows для своего приложения Angular 4, которое обращается к веб-API ASP.Net для всех своих потребностей в данных. У меня есть контроллер в моем веб-API с именем AuthenticationController с методом с именем Authenticate, который возвращает домен\имя пользователя, если аутентификация прошла успешно. Код для AuthenticationController выглядит следующим образом:

namespace MyAppWebAPI.Controllers
{
    [Authorize]
    public class AuthenticationController : ApiController
    {
        [HttpGet]
        public LoginModels Authenticate()
        {
            Debug.Write($"AuthenticationType: {User.Identity.AuthenticationType}");
            Debug.Write($"IsAuthenticated: {User.Identity.IsAuthenticated}");
            Debug.Write($"Name: {User.Identity.Name}");

            if (User.Identity.IsAuthenticated)
            {
                //return Ok($"Authenticated: {User.Identity.Name}");
                return new LoginModels { DomainName = User.Identity.Name, Role = "Admin" };
            }
            else
            {
                throw new Exception ("Not authenticated");
            }
        }
    }
}

Где LoginModels — это следующая модель:

public class LoginModels
{
    public string DomainName { get; set; }
    public string Role { get; set; }
}

Я включил CORS в моем WebApiConfig.cs в папке AppStart, и код для этого выглядит следующим образом:

namespace MyAppWebAPI
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services
            config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));

            // Web API routes
            config.MapHttpAttributeRoutes();
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{action}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

            //Resolve CORS Issue
            var cors = new EnableCorsAttribute("http://MyAngularApplicationIP:port", "*", "*") { SupportsCredentials = true };
            config.EnableCors(cors);
        }
    }
}

Кроме того, я включил аутентификацию Windows в моем Web.config:

<authentication mode="Windows"/>
    <authorization>
        <deny users="?" />
    </authorization>
</system.web>

Теперь в моем приложении Angular у меня есть служба с именем AuthenticationHelperService следующим образом:

@Injectable()
export class AuthenticationHelperService {

    constructor(
        private _httpHelperService: HttpHelperService,
        private _http: Http,
        private _requestOptions: RequestOptions,
    ) { }

    public authenticateUser(): Observable<any> {
        console.log('Calling GetUser');
        let headers = new Headers({ 'Content-Type': 'application/json' });
        let options = new RequestOptions({ headers: headers, withCredentials: true });
        return this._http
            .get('WebApiURL:port/api/Authentication/Authenticate', options)
            .map(this._httpHelperService.extractData)
            .catch(this._httpHelperService.handleError);
    }
}

Обратите внимание, что я включил withCredentials: true в опции запроса. Кроме того, здесь _httpHelperService.extractData просто преобразует мой ответ в JSON, а _httpHelperService.handleError регистрирует ошибку (если она есть) в консоли. Теперь я вызываю этот сервисный метод из компонента при загрузке страницы в методе ngOnInit следующим образом:

export class MasterComponent implements OnInit {

    constructor(
        private _userLoginService : UserLoginService,
        private _authenticationHelperService: AuthenticationHelperService
    ) { }

    private userName: any;

    ngOnInit() {
        this._authenticationHelperService.authenticateUser().subscribe(
            data => this.userName = data,
            error => console.log('Authentication Error :: ' + error),
            () => console.log('Current User :: ' + this.userName));
    }
}

Когда я запускаю приложение, браузер просит меня ввести учетные данные - Пожалуйста, посмотрите изображение После ввода учетных данных я попадаю на домашнюю страницу, но метод _authenticationHelperService.authenticateUser() не возвращает имя пользователя. Я получаю сообщение об ошибке в консоли следующим образом:

XMLHttpRequest не может загрузить «MyWebApiURL/api/Authentication/Authenticate». Ответ на предварительный запрос не проходит проверку управления доступом: в запрошенном ресурсе отсутствует заголовок «Access-Control-Allow-Origin». Таким образом, источник "MyAngularAppUrl" не имеет доступа. В ответе был код состояния HTTP 401.

Когда я просто вызываю метод аутентификации веб-API из браузера, например http://MyWebApiIP:port/api/Authentication/Authenticate, я успешно получаю свое имя пользователя, но не из приложения Angular.


person Amit Anand    schedule 26.05.2017    source источник
comment
Предварительный запрос CORS не работает, он должен вернуть HTTP 200, но вместо этого получает 401. Посмотрите, помогает ли этот пример понять, как настроить CORS в вашем веб-API docs.microsoft.com/en-us/aspnet/web-api/ обзор/безопасность/   -  person andresm53    schedule 26.05.2017
comment
Вам удалось решить эту проблему? Если да, то какое решение?   -  person Ben Cameron    schedule 01.08.2017
comment
@BenCameron Я следовал этому руководству: spikesapps.wordpress.com/2016/09/08/ и все отлично работает.   -  person Reed    schedule 03.05.2018


Ответы (2)


В дополнение к

Аутентификация Windows

вам также необходимо включить

Анонимная Аутентификация

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

просто не забудьте [Авторизовать] все ваши контроллеры.

person Paw Ormstrup Madsen    schedule 07.11.2018

запускSettings.json

вы можете найти этот файл в своем проекте в папке свойств,

{
  "iisSettings": {
    "windowsAuthentication": true,
    "anonymousAuthentication": false,
    "iisExpress": {
      "applicationUrl": "http://localhost:53072/",
      "sslPort": 0
    }
  },
  "profiles": {
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "AdvantureWeb": {
      "commandName": "Project"
    }
  }
}

перейти на оконную аутентификацию

person AQEEL AHMED    schedule 29.06.2017