Enable CORS for Web Api 2 and OWIN token authentication

后端 未结 3 1084
走了就别回头了
走了就别回头了 2020-12-23 10:22

I have an ASP.NET MVC 5 webproject (localhost:81) that calls functions from my WebApi 2 project (localhost:82) using Knockoutjs, to make the communication between the two p

3条回答
  •  攒了一身酷
    2020-12-23 10:34

    Solving the problem without using app.UseCors()

    I had the same problem. I used a Vue.Js client with axois to access my REST-API with cross-corps. On my Owin-Api-Server I was not able to add Microsoft.Owin.Cors nuget due to version conflicts with other 3rd party components. So I couldn't use app.UseCors() method but I solved it by using the middleware pipeline.

    private IDisposable _webServer = null;
    
    public void Start(ClientCredentials credentials)
    {
        ...
        _webServer = WebApp.Start(BaseAddress, (x) => Configuration(x));
        ...
    }
    
    public void Configuration(IAppBuilder app)
    {
        ...
        // added middleware insted of app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
        app.Use();
        app.UseWebApi(config);
        ...
    }
    
    public class MyOwinMiddleware : OwinMiddleware
    {
        public MyOwinMiddleware(OwinMiddleware next) :
            base(next)
        { }
    
        public override async Task Invoke(IOwinContext context)
        {
            var request = context.Request;
            var response = context.Response;
    
            response.OnSendingHeaders(state =>
            {
                var resp = (IOwinResponse)state;
    
                // without this headers -> client apps will be blocked to consume data from this api
                if (!resp.Headers.ContainsKey("Access-Control-Allow-Origin"))
                    resp.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
                if (!resp.Headers.ContainsKey("Access-Control-Allow-Headers"))
                    resp.Headers.Add("Access-Control-Allow-Headers", new[] { "*" });
                if (!resp.Headers.ContainsKey("Access-Control-Allow-Methods"))
                    resp.Headers.Add("Access-Control-Allow-Methods", new[] { "*" });
    
                // by default owin is blocking options not from same origin with MethodNotAllowed
                if (resp.StatusCode == (int)HttpStatusCode.MethodNotAllowed &&
                    HttpMethod.Options == new HttpMethod(request.Method))
                {
                    resp.StatusCode = (int)HttpStatusCode.OK;
                    resp.ReasonPhrase = HttpStatusCode.OK.ToString();
                }
    
            }, response);
    
            await Next.Invoke(context);
        }
    }
    

    So I created my own middleware and manipulated the response. GET calls only needed the Access-Control-Allow headers whereas for OPTIONS calls I also needed to manipulate the StatusCode because axois.post() is calling first with OPTIONS-method before sending the POST. If OPTIONS return StatusCode 405, the POST will never be sent.

    This solved my problem. Maybe this can help somebody too.

提交回复
热议问题