CORS 无法在具有 OWIN 身份验证的 Web api 中工作

Posted

技术标签:

【中文标题】CORS 无法在具有 OWIN 身份验证的 Web api 中工作【英文标题】:CORS is not working in web api with OWIN authentication 【发布时间】:2014-09-19 07:37:10 【问题描述】:

在我的应用程序中,我使用带有基于令牌的身份验证和 CORS 支持的 web api,但是当客户端请求令牌时,由于 CORS(跨源请求被阻止:同源策略不允许读取远程资源) (我的站点名称)。可以通过将资源移动到同一域或启用 CORS 来解决此问题。)

我已经配置了 CORS 支持所需的一切(我认为是这样)。这是我的配置

欧文启动课

   public class Startup
    
        public void Configuration(IAppBuilder app)
        


            var config = new HttpConfiguration
            
                DependencyResolver = new StructureMapWebApiDependencyResolver(container)

            ;


            WebApiConfig.Register(config);  // registering web api configuration
            app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);  // cors for owin token pipeline
            app.UseWebApi(config);
            ConfigureOAuth(app);


        

        public void ConfigureOAuth(IAppBuilder app)
        
            var oAuthAuthorizationServerOptions = new OAuthAuthorizationServerOptions()
            

                AllowInsecureHttp = true,
                TokenEndpointPath = new PathString("/token"),
                AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
                Provider = new SimpleAuthorizationServerProvider()
            ;
            // Token Generation
            app.UseOAuthAuthorizationServer(oAuthAuthorizationServerOptions);
            app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());

        
    

还有我的 webapi 配置

public static class WebApiConfig
    
        public static void Register(HttpConfiguration config)
        
            config.EnableCors();  // Corse support for Web api
            config.MapHttpAttributeRoutes(); // attribute based urls

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/controller/id",
                defaults: new  id = RouteParameter.Optional 
            );

        
    

这里在web.config中配置

<system.webserver>
 <httpProtocol>
      <customHeaders>
        <!-- Adding the following custom HttpHeader will help prevent CORS from stopping the Request-->
        <add name="Access-Control-Allow-Origin" value="*" />
        <add name="Access-Control-Allow-Methods" value="GET, POST, OPTIONS, PUT, DELETE" />
      </customHeaders>
    </httpProtocol>
</system.webserver>

和我来自 mozilla 的请求标头

Accept  application/json, text/plain, */*
Accept-Encoding gzip, deflate
Accept-Language en-US,en;q=0.5
Content-Length  67
Content-Type    application/x-www-form-urlencoded; charset=UTF-8
Host    talenterp
Origin  http://192.168.1.11:85
Referer http://192.168.1.11:85/
User-Agent  Mozilla/5.0 (Windows NT 6.3; WOW64; rv:30.0) Gecko/20100101 Firefox/30.0

应用的网址是

服务器应用(应该支持 CORS)

http://talenterp

令牌终点:

http://talenterp/token

客户端应用

http://talentmvc:85

注意:我已经添加了

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

在我的 AuthorizationServerProvider 的 GrantResourceOwnerCredentials() 方法中

【问题讨论】:

已解决.. 问题出在配置 CORS app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll); config.EnableCors(); context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] "*" );我刚刚删除了第一个 嗨!这真的对你有用吗?谢谢。 删除 config.EnableCors() 行而不是 app.UserCors() 可能更好。前者不使用 OWIN,后者使用。展望未来,最好使用 OWIN 管道设置。 @BinsonEldhose 请接受回答。 您还需要从 web.config 中删除 ,参见***.com/a/33664502/631527 【参考方案1】:

确保你只有

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

已配置,也是 Global.asax 或 WebApiConfig 中的旧样式“config.EnableCors()”。此外:将上述语句作为您自己的 Startup 类中的第一个语句。是的,这确实很重要,稍后设置它也会导致 cors 不起作用。

public partial class Startup

    public void Configuration(IAppBuilder app)
    
        app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);

        ... etc

【讨论】:

本文介绍了如何提供自定义 CORS 策略:benfoster.io/blog/aspnet-webapi-cors 如今这应该被标记为正确答案。谢谢! 将 UseCors 调用移至 Configuration 方法中的第一个,它解决了我们的 405 问题。 Postman 工作正常,但它是来自 Chrome 的 405ing。 将行移到配置方法的顶部也修复了我的问题。谢谢! 一次又一次@Pogrindis。某种“stackenfreude”,您会为自己的不幸感到高兴,因为它会引导您回到您完全忘记的自己的 *** 答案。这种情况发生的频率令人惊讶。【参考方案2】:

特别是如果您在使用 CORS 时遇到 Web API 不记名令牌问题,那么不要忘记将“TOKEN”放入您允许的方法列表中。

请将代码放在你的web.config的system.webServer中,我就是这样解决的

<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Methods" value="GET, POST, OPTIONS, PUT, DELETE, TOKEN" />
 </customHeaders>

【讨论】:

将 TOKEN 添加到值解决了我的问题,而所有其他解决方案都不起作用!【参考方案3】:

OWIN 和 Microsoft.AspNet.WebApi.Cors 是两个独立的库,每个都需要单独的配置。

在 OWIN 中禁用 CORS:

public void Configuration(IAppBuilder app)

        //app.UseCors(CorsOptions.AllowAll);

找到 GrantResourceOwnerCredentials 方法并将 Access-Control-Allow-Origin 添加到上下文中,这样当它在身份验证完成后返回调用时,浏览器会找到并接受它。

public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)

        context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[]  "http://localhost" );

现在将 Microsoft.AspNet.WebApi.Cors 包从 Nuget 安装到您的 webapi 项目,并将其添加到注册方法

public static void Register(HttpConfiguration config)

        var cors = new EnableCorsAttribute("http://localhost, ", "accept,accesstoken,authorization,cache-control,pragma,content-type,origin", "GET,PUT,POST,DELETE,TRACE,HEAD,OPTIONS");

        config.EnableCors(cors);

这是为我做的。

【讨论】:

实际上这对我有用,对于 owin 上的更高版本,这解决了。 +1 我知道距离您发布此答案已经过去了将近 6 个月,但也许您还记得这一点。我很感兴趣,你为什么在 var cors=new EnableCorsAttribute("http: //localhost, "... 中写 "http://localhost," 而不是 var cors=new EnableCorsAttribute("http: //localhost “...?我的意思是我对“http://localhost 之后的“,”(逗号和空格)感到困惑 @Dato 这绝对是我代码中的域列表的剩余部分。 EnableCorsAttribute 允许您在一个字符串中传递域列表。这是参考link @DadoKljuco 感谢您的回复。有趣的是 var cors=new EnableCorsAttribute("http: //localhost, "... 效果很好但是 var cors=new EnableCorsAttribute("http: //localhost"... 失败了。这就是我为什么困惑【参考方案4】:

我遇到了类似的问题,我在 startup.cs 中尝试了上述所有选项,我添加了 app.UseCors(CorsOptions.AllowAll);在顶部和我禁用的 WebApiConfig 中

public static void Register(HttpConfiguration config)

    //var cors = new EnableCorsAttribute("*", "*", "*");
    //config.EnableCors(cors);

并且在

中也禁用了cors
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)

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

并以相反的顺序重复此操作,并在 web.config 中包含条目,但均无效。

当我开始问自己为什么 app.UseWebApi(config); 无法访问时,我已经看到它在某个地方工作。我环顾四周,发现安装Install-Package Microsoft.AspNet.WebApi.OwinSelfHost 修复了它。

最终,它解决了整个问题,尽管 app.UseCors(CorsOptions.AllowAll) 必须放在 startup.cs 方法的首位。事实上,没有app.UseWebApi(config),我在邮递员中进行了测试,端点实际上并不存在。总的来说,它现在对我来说效果很好。

【讨论】:

【参考方案5】:

遇到了同样的问题。除了上述指示(仅使用 app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll) 并将其设置为第一件事),我必须在应用程序 Web.config 文件中指定以下内容才能处理选项请求:

<system.webServer>
<handlers>
  <remove name="ExtensionlessUrlHandler-Integrated-4.0"/>
  <remove name="OPTIONSVerbHandler"/>
  <remove name="TRACEVerbHandler"/>          
  <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0"/>
</handlers>
</system.webServer>

由于我在身份验证请求中发送了一些标头,因此在实际 POST 请求之前发送了一个 Options 请求,并且它需要在发送 POST 之前返回正确的“Access-Control-Allow-Origin”标头。

如果选项响应没有返回任何 CORS 标头,则根本不会发送 POST。添加的配置支持此行为以及 Trace。

正如post中所解释的那样

【讨论】:

对我来说,我必须确保我删除了 OPTIONSVerbHandler,否则 OWIN Cors 解决方案没有做任何事情(代码运行,但没有发生任何事情)。

以上是关于CORS 无法在具有 OWIN 身份验证的 Web api 中工作的主要内容,如果未能解决你的问题,请参考以下文章

具有混合身份验证 JWT 和 SAML 的 ASP.NET Web API 2.2 OWIN

WebApi 上的 AngularJS 和 OWIN 身份验证

Web API 2,OWIN 身份验证,SignOut 不注销

具有多个 OIDC 身份验证配置的 OWIN

身份验证/授权 MVC 5 和 Web API - Katana/Owin

是否可以配置 OWIN Cookie 身份验证以防止某些 URL 影响滑动过期?