usecors optionsverbhandler microsoft corsoptions app allowall asp.net-web-api asp.net-mvc-5 cors asp.net-web-api2 owin

asp.net web api - optionsverbhandler - Habilitar CORS para Web Api 2 y autenticación de token OWIN



microsoft owin cors (2)

Tengo un proyecto web ASP.NET MVC 5 (localhost: 81) que llama a las funciones de mi proyecto WebApi 2 (localhost: 82) usando Knockoutjs, para establecer la comunicación entre los dos proyectos que habilito CORS. Todo funciona hasta ahora, hasta que intenté implementar la autenticación de token OWIN en WebApi.

Para usar el punto final / token en WebApi, también necesito habilitar CORS en el punto final, pero después de horas de intentar y buscar soluciones, todavía está funcionando y el api / token aún genera:

XMLHttpRequest cannot load http://localhost:82/token. No ''Access-Control-Allow-Origin'' header is present on the requested resource. public void Configuration(IAppBuilder app) { app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll); TokenConfig.ConfigureOAuth(app); ... }

TokenConfig

public static void ConfigureOAuth(IAppBuilder app) { app.CreatePerOwinContext(ApplicationDbContext.Create); app.CreatePerOwinContext<AppUserManager>(AppUserManager.Create); OAuthAuthorizationServerOptions OAuthServerOptions = new OAuthAuthorizationServerOptions() { AllowInsecureHttp = true, TokenEndpointPath = new PathString("/token"), AccessTokenExpireTimeSpan = TimeSpan.FromDays(1), Provider = new SimpleAuthorizationServerProvider() }; app.UseOAuthAuthorizationServer(OAuthServerOptions); app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions()); }

Proveedor de Autorizacion

public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) { context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" }); var appUserManager = context.OwinContext.GetUserManager<AppUserManager>(); IdentityUser user = await appUserManager.FindAsync(context.UserName, context.Password); if (user == null) { context.SetError("invalid_grant", "The user name or password is incorrect."); return; } ... claims }

IdentityConfig

public static AppUserManager Create(IdentityFactoryOptions<AppUserManager> options, IOwinContext context) { // Tried to enable it again without success. //context.Response.Headers.Add("Access-Control-Allow-Origin", new[] {"*"}); var manager = new AppUserManager(new UserStore<AppUser>(context.Get<ApplicationDbContect>())); ... var dataProtectionProvider = options.DataProtectionProvider; if (dataProtectionProvider != null) { manager.UserTokenProvider = new DataProtectorTokenProvider<AppUser>(dataProtectionProvider.Create("ASP.NET Identity")); } return manager; }

EDITAR:

1. Nota importante: la apertura directa del punto final (localhost: 82 / token) funciona.

2. Llamar a Api (localhost: 82 / api / ..) desde el proyecto web también funciona, por lo que CORS está habilitado para WebApi.


Sé que su problema se resolvió con comentarios, pero creo que es importante entender qué lo causó y cómo resolver toda esta clase de problemas.

Observando su código, puedo ver que está configurando el encabezado Access-Control-Allow-Origin más de una vez para el punto final del token:

app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);

Y dentro del método GrantResourceOwnerCredentials :

context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });

Esto, considerando las especificaciones CORS , es en sí mismo un problema porque:

Si la respuesta incluye cero o más de un valor de encabezado Access-Control-Allow-Origin, devuelva fail y finalice este algoritmo.

En su escenario, el marco está configurando este encabezado dos veces, y al comprender cómo se debe implementar CORS, esto provocará que se elimine el encabezado en ciertas circunstancias (posiblemente relacionado con el cliente).

Esto también se confirma con la siguiente respuesta de la pregunta: Duplicar acceso-control-permitir-origen: * ¿causando un error de COR?

Por esta razón, mover la llamada a app.UseCors después de la llamada a ConfigureOAuth permite que su encabezado CORS se establezca solo una vez (porque la tubería de Owin se interrumpe en el middleware OAuth, y nunca llega al middleware Microsoft CORS para el punto final de Token ) y hace tu llamada Ajax funcionando.

Para una solución mejor y global, puede intentar volver a poner app.UseCors antes de la llamada de middleware OAuth, y eliminar la segunda inserción de Access-Control-Allow-Origin dentro de GrantResourceOwnerCredentials .


Sigue los pasos a continuación y tendrás tu API funcionando:

  1. Elimine cualquier código como config.EnableCors(), [EnableCors(header:"*"....)] de su API.
  2. Ir a startup.cs y agregar debajo de la línea

    app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);

antes de

ConfigureAuth(app);

Uou también necesitará instalar el paquete Microsoft.owin.cors para usar esta funcionalidad