从我的自定义中间件返回到角度时,asp .net core api cors 问题

Posted

技术标签:

【中文标题】从我的自定义中间件返回到角度时,asp .net core api cors 问题【英文标题】:asp .net core api cors issue when returning from my custom middleware to angular 【发布时间】:2020-01-17 23:26:35 【问题描述】:

我正在为我的 Angular 应用程序构建一些 .net core api 我想同时使用windows authenticationjwt,因为请求只能有一个身份验证标头-我在自己的“CustomAuthorization”标头中传递我的令牌,因此默认情况下可以存在Windows身份验证。 所以我加了

  app.UseMiddleware<CheckCustomHeader>();

我构建了我的中间件

public  class CheckCustomHeader

    private readonly RequestDelegate _next;

    public CheckCustomHeader(RequestDelegate next)
    
        _next = next;
    
    public async Task Invoke(HttpContext context)
    

        if (context.Request.Method == HttpMethods.Post)
        
            string token = context.Request.Headers["CustomAuthorization"];

            try
            
                string secret = "MySecreetKey";
                        var key = Encoding.ASCII.GetBytes(secret);
                        var handler = new JwtSecurityTokenHandler();
                        var validations = new TokenValidationParameters
                        
                            ValidateIssuerSigningKey = true,
                            IssuerSigningKey = new SymmetricSecurityKey(key),
                            ValidateIssuer = false,
                            ValidateAudience = false
                        ;           
                        var claims = handler.ValidateToken(token, validations, out var tokenSecure);
                        var x = claims.Identity.Name;
                       //toDo - check if this token identityName = windows auth identity 
            
            catch (System.Exception)
            
                context.Response.Clear();
                context.Response.ContentType = "text/plain; charset=utf-8";
                context.Response.StatusCode = StatusCodes.Status400BadRequest;
                await context.Response.WriteAsync("Invalid User Key");      
                // return ? // should it be there? i tryied both cases ;)           
            
        

        await _next(context);
    

而且效果很好——如果钥匙没问题,那就没问题了 但是当 jwt 键不正确时,我想捕获异常并返回这个 badrequest。 在postman 中没关系 - 它返回 400 并且正文中的此消息, 但是从我的角度应用程序中我得到了

 Access to XMLHttpRequest at 'http://localhost:51500/SP/t/generateReport/' from origin 
 'http://localhost:4200' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is 
 present on the requested resource.
 data.service.ts:43 unCatch DataService post error:0"headers":"normalizedNames": 
 ,"lazyUpdate":null,"headers":,"status":0,"statusText":"Unknown Error",url":"http://localhost:51500/SP/t/generateReport","ok":false,"name":"HttpErrorResponse","message":"Http failure response for http://localhost:51500/SP/t/generateReport/: 0 Unknown Error","error":"isTrusted":true
 zone-evergreen.js:2828 POST http://localhost:51500/SP/t/generateReport/ net::ERR_FAILED

就像任何 cors 被阻止的请求一样 - 为什么? 我已经配置了 corse,并且很适合所有其他请求... 我应该根据我的请求为这个 owerwriten 手动添加一些 cors 标头吗?或者我应该如何在中间件中返回这个错误?

感谢和问候!

编辑 cors 策略就是这样添加的

  string[] HostOrigins = new string[]  "http://localhost:4200", "https://localhost:4200";

        services.AddCors(options =>    
        

            options.AddPolicy("CorsPolicy", builder =>
            
                builder.WithOrigins(a.CorsSettings.Origins)
                        .AllowAnyHeader().AllowAnyMethod().AllowCredentials();
            );

        );

然后

   app.UseCors("CorsPolicy");

【问题讨论】:

如何添加 cors 支持? 我在编辑中添加了 【参考方案1】:

我找到了解决办法 当我手动添加 cors 标题时它可以工作

                context.Response.Clear();
                context.Response.Headers.Add("Access-Control-Allow-Origin", "http://localhost:4200");
                context.Response.Headers.Add("Access-Control-Allow-Methods", "POST");
                context.Response.Headers.Add("Access-Control-Allow-Credentials", "true");


                context.Response.ContentType = "text/plain; charset=utf-8";
                context.Response.StatusCode = StatusCodes.Status400BadRequest; 
                await context.Response.WriteAsync("Invalid User Key");

所以是的,这是 cors 问题 - 在这种方法中,cors 策略在“手动”生成响应时不使用。 但我对此并不满意——有人知道如何用这种“正确的方式”吗? 问候

-----编辑-----

如此简单 - 订单很重要! 有就够了

 app.UseCors("CorsPolicy");

之前

 app.UseMiddleware<CheckCustomHeader>();

我有... ;/ ;P

【讨论】:

【参考方案2】:

您可以尝试以下方法:

安装“Microsoft.AspNet.WebApi.Cors”。 (只需在 PM 控制台中运行以下命令。

安装包 Microsoft.AspNet.WebApi.Cors

发布此打开文件 App_Start/WebApiConfig.cs。将以下代码添加到 WebApiConfig.Register 方法中:

config.EnableCors();

您的示例文件将如下所示:

using System.Web.Http;
namespace WebService

    public static class WebApiConfig
    
        public static void Register(HttpConfiguration config)
        
            // New code
            config.EnableCors();

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

接下来,将 [EnableCors] 属性与源、标头和方法一起添加到您的中间件所在的控制器中。要允许所有请求,请在标头和方法字段中使用“*”。

例子:

using System.Net.Http;
using System.Web.Http;
using System.Web.Http.Cors;

namespace WebService.Controllers

    [EnableCors(origins: "http://www.mywebsite.com", headers: "*", methods: "*")]
    public class TestController : ApiController
    
        // Controller methods not shown...
    

注意:这可以在动作级别、控制器级别以及为您的应用程序全局添加。

要在全局范围内使用它,WebApiConfig 将如下所示:

public static class WebApiConfig

    public static void Register(HttpConfiguration config)
    
        var cors = new EnableCorsAttribute("www.mywebsite.com", "*", "*");
        config.EnableCors(cors);
        // ...
    

【讨论】:

我认为它适用于 .net 框架而不是 .net 核心,它并不能以任何方式解决我的问题 - 通常是如何启用 cors,我已经做到了,问题不同

以上是关于从我的自定义中间件返回到角度时,asp .net core api cors 问题的主要内容,如果未能解决你的问题,请参考以下文章

从我的 ASP.NET 站点在 Android 3.0 浏览器中下载文件

处理asp.net核心中的异常?

Asp.Net WebApi 上的自定义授权属性

如何将消息从我的存储库类返回到我的控制器,然后返回到我在 asp.net-mvc 中的视图?

如何从 ASP.NET Core 2.0 中的自定义中间件请求身份验证

Asp.Net 5 TagHelper 模型状态绑定