Как исправить веб-приложение реагировать на ошибку авторизации .net webapi - PullRequest
0 голосов
/ 24 мая 2019

У меня есть приложение, в котором веб-интерфейс (реагировать) и веб-API (.net) развернуты на двух разных серверах. Однако, когда я устанавливаю свою аутентификацию API на Windows, она продолжает выдавать ошибку: Failed to load resource: the server responded with a status of 401 (Unauthorized)

Я могу просматривать ссылку на развернутое приложение, когда у меня есть следующие настройки:
UI Site: Windows Authentication<br> API Site: Anonymous Authentication.

Но это не помогает мне получить зарегистрированный идентификатор пользователя. Это возвращает имя iis / app-pool как зарегистрированный пользователь.

Итак, я изменил настройки на следующие:
UI Site: Windows Authentication<br> API Site: Windows Authentication and ASP.NET Impersonation.

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

Я попробовал различные решения, предложенные в Интернете, включая шаги с 1 по 4 для следующего: Как передать учетные данные для проверки подлинности Windows от клиента в службу веб-API , но пока безуспешно.

Кто-нибудь сталкивался с такой проблемой и нашел исправление?

Edit: Я продолжил шаги, предложенные Александром Родригесом в ответе ниже. Я включил CORS, как описано в ссылке.

Первый выпуск был: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

Итак, я добавил путь к сайту:

[EnableCors(origins: "http:myexample.com", headers: "*", methods: "*", SupportsCredentials = true)] 

Это исключительно не помогло, тогда я добавил следующие строки в web.config:

<httpProtocol>
   <customHeaders>
      <add name="Access-Control-Allow-Methods" value="POST,GET" />
      <add name="Access-Control-Allow-Origin" value="http://myexample.com" /> 
      <add name="Access-Control-Allow-Credentials" value="true" />
      <add name="Access-Control-Allow-Headers" value="cache-control,content-type,man,messagetype,soapaction" />
   </customHeaders>
</httpProtocol>

Следующая ошибка, которую я получил, была:

The value of the 'Access-Control-Allow-Credentials' header in the response is 'true, true' which must be 'true'.

и

The value of the 'Access-Control-Allow-Origin' header in the response is 'http://myexample.com, http://myexample(index).com' which must be 'http://myexample.com'

Итак, в крайнем случае, я прокомментировал ниже строку из моего WebAPI и повторно развернул приложение.

[EnableCors(origins: "http:myexample.com", headers: "*", methods: "*", SupportsCredentials = true)]

Это сработало! Это привело к тому, что приложение показало результат для обоих контроллеров: один, где я установил Авторизацию, а другой без Авторизации.

Ошибки генерировались только контроллером, к которому я добавил [Авторизовать], потому что другой чаще всего возвращал результат.

Итак, мой вопрос: так должны работать обычные аутентификация и авторизация или я прокомментировал очень важную часть Авторизации? Обновить: Так что это делает только GET запросы на работу, а не POST. Заголовок запроса: Access-Control-Allow-Credentials: true Access-Control-Allow-Headers: cache-control,content-type,man,messagetype,soapaction Access-Control-Allow-Methods: POST,GET Access-Control-Allow-Origin: http://myexample.com **Response Header** Provisional headers are shown Access-Control-Request-Headers: content-type Access-Control-Request-Method: POST Origin: http://myexample.com Referer: http://myexample.com/form/1001 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36

1 Ответ

1 голос
/ 24 мая 2019

Предпосылка

Чтобы получить доступ к любому веб-API из Reactjs или любого метода Ajax, веб-API должен включить CORS

Фрагмент кода веб-конфигурации

<system.web>  
    <authentication mode="Windows" ></authentication>  
</system.web>  

Использовать Атрибут авторизации на контроллере или любом другом методе действий для безопасности

пример

[EnableCors(origins: "*", headers: "*", methods: "*", SupportsCredentials = true)]  
    public partial class WebAPIController : ApiController  
    {  

        [HttpGet]  
        [Authorize]  
        [Route("api/AuthenticateUser")]  

        public HttpResponseMessage AuthenticateUser()  
        {  
            if (User != null)  
            {  
                 return Request.CreateResponse(HttpStatusCode.OK, new  
                {  
                    status = (int)HttpStatusCode.OK,  
                    isAuthenticated = true,  
                    isLibraryAdmin = User.IsInRole(@"domain\AdminGroup"),  
                    username = User.Identity.Name.Substring(User.Identity.Name.LastIndexOf(@"\") + 1)  
                });  
            }  
            else  
            {  
//This code never execute as we have used Authorize attribute on action method  
                return Request.CreateResponse(HttpStatusCode.OK, new  
                {  
                    status = (int)HttpStatusCode.BadRequest,  
                    isAuthenticated = false,  
                    isLibraryAdmin = false,  
                    username = ""  
                });  

            }  
         }  
    }

Этот атрибут [Authorize] гарантирует, что действие будет выполнено только в том случае, если пользователь ввел действительные учетные данные, в противном случае будет отображаться 401 Несанкционированный доступ.

Если вы получили «Авторизация была отклонена для этого запроса», отметьте это сообщение

Итак, исходя из предоставленного решения, приведенного выше, вопрос переполнения стека требует немного больше настроек для проверки подлинности Windows () в файле «applicationhost.config», который находится в корневом каталоге проекта «.vs \ config», эта папка скрыта вами необходимо включить опцию показать все скрытые файлы и папки.

<windowsAuthentication enabled="true">
   <providers>
       <add value="Negotiate" />
       <add value="NTLM" />
       </providers>
</windowsAuthentication>

CORS включен со стороны сервера. Теперь при запросе API передайте флаг withCredentials: true из внешнего интерфейса.

Для jQuery Ajax вы должны передать запрос, как показано ниже.

$.ajax({url:apiURL ,xhrFields: {   withCredentials: true }, success:successHandler }); 

Для Reactjs вы должны передать запрос, как показано ниже.

private options = new RequestOptions({ withCredentials: true });  
this.http.get(this.baseUrl, this.options) 

Ajax Snippet

var apiURL="http://localhost:51647/api/AuthenticateUser";  
$.ajax({
    url:apiURL ,
    xhrFields: { withCredentials: true }, 
    success: function(result){  
    console.log(JSON.stringify(result));  
}});    

Отредактировано

Давайте включим CORS

Предполетные запросы (ОПЦИИ)

<system.web>
    <authentication mode="Windows" />
    <authorization>
        <allow verbs="OPTIONS" users="*"/>
        <deny users="?" />
    </authorization>
</system.web>

Global.asax.cs

protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
    if (Context.Request.HttpMethod == "OPTIONS")
    {
        if (Context.Request.Headers["Origin"] != null)
            Context.Response.AddHeader("Access-Control-Allow-Origin", Context.Request.Headers["Origin"]);

        Context.Response.AddHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, MaxDataServiceVersion");
        Context.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        Context.Response.AddHeader("Access-Control-Allow-Credentials", "true");

        Response.End();
    }
}

Включение CORS

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // all requests are enabled in this example. SupportsCredentials must be here to allow authenticated requests          
        var corsAttr = new EnableCorsAttribute("*", "*", "*") { SupportsCredentials = true };
        config.EnableCors(corsAttr);
    }
}

protected void Application_Start()
{
    GlobalConfiguration.Configure(WebApiConfig.Register);
}

пример

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