405 WebAPI2上不允许的方法(OWIN)

时间:2015-01-18 19:13:03

标签: angularjs asp.net-web-api cors asp.net-web-api2 owin

我正在为我的API设置一个WebAPI端点,但是在使用我的PostRegister方法调用AngularJS时遇到问题。

webAPI和Angular位于不同的网站上。

在Startup.cs上我有:

    public void Configuration(IAppBuilder app)
    {
        ConfigureOAuth(app);

        var config = new HttpConfiguration();

        WebApiConfig.Register(config);
        app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
        app.UseWebApi(config);

    }

    private void ConfigureOAuth(IAppBuilder app)
    {
        var oAuthServerOptions = new OAuthAuthorizationServerOptions
        {
            AllowInsecureHttp = true,
            TokenEndpointPath = new PathString(Paths.TokenPath),
            AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30),
            Provider = Kernel.Get<IOAuthAuthorizationServerProvider>()
        };
        app.UseOAuthAuthorizationServer(oAuthServerOptions); 

        OAuthBearerOptions = new OAuthBearerAuthenticationOptions();
        app.UseOAuthBearerAuthentication(OAuthBearerOptions);
    }

然后在控制器上,我的方法被设置为允许匿名:

    [AllowAnonymous]
    public bool PostRegister(UserSignupForm form)
    {
        ...
    }

我还更新了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>

在Angular方面,我做了一个简单的$ http.post调用:

    saveRegistration: function (registration) {
        return $http.post(baseUrl + '/api/signup/register', registration).then(function (response) {
            return response;
        });
    }

使用Postman进行调用时,我得到了一个成功的响应,但是当从Angular执行相同的调用时,我得到405错误。

405 Method Not Allowed

BitOfTech示例网站,正在发送相同的请求标头,但能够获取Access-Control-Allow-XXX标头

enter image description here

我已更新我的代码以关注Token Based Authentication using ASP.NET Web API 2, Owin, and Identity

5 个答案:

答案 0 :(得分:10)

我最近遇到过类似的问题。我为飞行前OPTIONS请求添加了控制器处理程序,它解决了问题。

[AllowAnonymous]
[Route("Register")]
[AcceptVerbs("OPTIONS")]
public async Task<IHttpActionResult> Register()
{
    return Ok();
}

答案 1 :(得分:4)

您可能需要在应用程序中允许使用响应头的cors。以下是我在节点中所做的示例。

res.header('Access-Control-Allow-Origin', '*');

res.header("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS"); 

res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');

这可以帮到你。感谢。

答案 2 :(得分:2)

问题不在于角度。虽然您在Postman中得到了回复,但请求中的角度没有问题并没有给您回复。问题是默认情况下邮递员不发布测试CORS所需的Origin attribute。 Chrome默认会阻止Origin属性,因此请求不会被视为来自其他域。

那么如何在Postman中测试CORS

您需要具有相同名称POSTMAN - Rest Client (Packaged App)的不同Chrome扩展程序,并使用其“请求拦截器”切换开关&#39;使其能够发送ORIGIN属性。

read here,第restricted header部分

下面的

是您不发送ORIGIN属性时拍摄的示例屏幕

WITHOUT ORIGIN

和相同的请求;当您发送ORIGIN属性时,在POSTMAN中的响应

WITH ORIGIN

所以如果你看到,当你添加原点时,只有当你得到ACCESS-CONTROL- *属性作为回应。

我希望这也能回答你关于

的问题
  

BitOfTech示例站点,正在发送相同的请求标头,但是   能够获得Access-Control-Allow-XXX标头&#34;

Web Api Part

回到你的案例,你没有在web-api中启用CORS。首先在web-api中启用CORS。要在全球范围内启用CORS,请使用

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        var cors = new EnableCorsAttribute("www.example.com", "*", "*");
        config.EnableCors(cors);
        // ...
    }
}

- 你可以在网上找到很多关于如何在控制器级别添加它的资源。

角色部分

首先需要确保CORS在POSTMAN中工作,然后尝试以角度访问该URL。

在app.config()函数中的代码下方启用角度的角色。

myApp.config(function($httpProvider) {
  $httpProvider.defaults.useXDomain = true;
  delete $httpProvider.defaults.headers.common['X-Requested-With'];
});

注意:专家

Origin attributes is needed to test CORS.我对这一部分不太确定,但根据我在邮递员中看到的回应,情况似乎如此。如果有人能够阐明科尔斯Origin attribute中的角色,那就太好了。

答案 3 :(得分:1)

这听起来像是一个跨学科的问题。您应该安装Fiddler并检查405响应是否是由您在调用不同来源的资源时由浏览器发出的飞行前请求(OPTIONS动词)引起的。

有关CORS的详细解释,请参阅此文章:http://www.html5rocks.com/en/tutorials/cors/

答案 4 :(得分:1)

我相信您在API控制器上缺少注释,您应该在APIController上添加注释

[RoutePrefix("api/signup")]

否则您的WebApiConfig应该具有类似于

的路径定义
public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }
    }

要设置CORS,您始终需要在每次调用服务器时发送您的凭据。 然后,通过设置 $http 提供程序默认选项,可以轻松地在角度中执行此操作。

您可以在角度配置阶段执行此操作。

<强> CODE

  angular.module('myApp',[])
    .config([
        '$httpProvider',
        function($httpProvider) {
            $httpProvider.defaults.withCredentials = true;
        }
    ]);

以上设置将在每个$ http呼叫中添加凭证。

另请参阅this帖子。有些同样的问题。

这可能有助于解决您的问题。 感谢。