Tengo solicitudes que son válidas cuando realizo solicitudes desde el navegador, pero a través de la aplicación Angular 9 recibo un error 401. Este es el encabezado de Chrome:
Request URL: http://localhost:1234/api/Common/GetMy_List Request Method: GET Status Code: 401 Referrer Policy: strict-origin-when-cross-origin Access-Control-Allow-Credentials: true Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, X-Token Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS Access-Control-Allow-Origin: http://localhost:4200 Access-Control-Allow-Origin: * Cache-Control: private Content-Length: 6069 Content-Type: text/html; charset=utf-8 Date: Wed, 06 Oct 2021 12:55:39 GMT Server: Microsoft-IIS/10.0 WWW-Authenticate: Negotiate WWW-Authenticate: NTLM X-Powered-By: ASP.NET Accept: application/json, text/plain, */* Accept-Encoding: gzip, deflate, br Accept-Language: he-IL,he;q=0.9,en-US;q=0.8,en;q=0.7 Connection: keep-alive Host: localhost:1234 Origin: http://localhost:4200 Referer: http://localhost:4200/ sec-ch-ua: "Chromium";v="94", "Google Chrome";v="94", ";Not A Brand";v="99" sec-ch-ua-mobile: ?0 sec-ch-ua-platform: "Windows" Sec-Fetch-Dest: empty Sec-Fetch-Mode: cors Sec-Fetch-Site: same-site User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36Tengo un proyecto angular 9 con un archivo proxy.conf.json declarado en package.json. el archivo contiene estas líneas:
{ "/api/*": { "target": "http://localhost:1234", "secure": true, "logLevel": "debug", "changeOrigin": true } }En el lado del servidor hay una API asp.net con estas líneas en global.asax:
public void Application_BeginRequest(object sender, EventArgs e) { string httpOrigin = Request.Params["HTTP_ORIGIN"]; if (httpOrigin == null) httpOrigin = "*"; HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", httpOrigin); HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS"); HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, X-Token"); HttpContext.Current.Response.AddHeader("Access-Control-Allow-Credentials", "true"); if (Request.HttpMethod == "OPTIONS") { HttpContext.Current.Response.StatusCode = 200; var httpApplication = sender as HttpApplication; httpApplication.CompleteRequest(); } }En la web.config:
<system.webServer> <httpProtocol> <customHeaders> <add name="Access-Control-Allow-Origin" value="*" /> </customHeaders> </httpProtocol> <validation validateIntegratedModeConfiguration="false" /> <directoryBrowse enabled="false" /> </system.webServer> <system.serviceModel> <behaviors> <endpointBehaviors> <behavior name="ImpersonateBehaviour"> <clientCredentials> <windows allowedImpersonationLevel="Delegation" /> </clientCredentials> </behavior> </endpointBehaviors> </behaviors> <bindings> <basicHttpBinding> <binding name="BasicHttpBinding_IService1" maxReceivedMessageSize="2147483647"> <security mode="TransportCredentialOnly"> <transport clientCredentialType="Windows" /> </security> </binding> </basicHttpBinding> </bindings> <client> <endpoint address="http://localhost/xxx.svc" behaviorConfiguration="ImpersonateBehaviour" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IService1" contract="Service1Ref.IService1" name="BasicHttpBinding_IService1" /> </client> </system.serviceModel>El navegador permite cualquier solicitud http al origen (url donde comenzó su sesión http). En las aplicaciones de una sola página, generalmente cargamos el DOM que internamente crea XHR adicionales para un nuevo dominio (generalmente una nueva aplicación web/api de descanso). Esto se considera una falla de seguridad y todos los navegadores modernos y de buena reputación dejaron de admitir este comportamiento.
Para mitigar esto, necesita un proxy en el dominio de origen. Todas las solicitudes para obtener datos deben pasar por él.
En angular puedes:
Sugiero usar el proxy CLI angular en lugar de agregar la configuración CORS.
Intente cambiar su Application_BeginRequest a esto. Cuando trato de usar el tuyo, falla en mi código. El siguiente código funciona.
protected void Application_BeginRequest(Object sender, EventArgs e) { if (HttpContext.Current.Request.HttpMethod == "OPTIONS") { HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS"); HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "X-Requested-With, Content-Type, Accept, X-Token"); HttpContext.Current.Response.AddHeader("Access-Control-Allow-Credentials", "true"); HttpContext.Current.Response.End(); } }Me di cuenta de que puedo ingresar Application_BeginRequest pero no en mi función en el controlador, lo que significa un problema de privilegio de CORES.
entonces, en el IIS, agregué autenticación anónima y ahora puedo hacer solicitudes de GET/POST y otras.
En IIS, elija su sitio en Sitios, luego haga doble clic en la categoría Autenticaciones, luego =>: