[C#] ASP.net Core WebAPI에서 CORS를 활성화하는 방법

내가하려는 일

Azure Free Plan (소스 코드 : https://github.com/killerrin/Portfolio-Backend )에서 호스팅되는 백엔드 ASP.Net Core Web API가 있습니다.

또한 API를 사용하려는 클라이언트 웹 사이트가 있습니다. 클라이언트 응용 프로그램은 Azure에서 호스팅되지 않지만 Github Pages 또는 내가 액세스 할 수있는 다른 웹 호스팅 서비스에서 호스팅됩니다. 이로 인해 도메인 이름이 정렬되지 않습니다.

이것을 살펴보면 웹 API 측에서 CORS를 활성화해야하지만 지금은 몇 시간 동안 거의 모든 것을 시도했지만 작동하지 않습니다.

클라이언트 설정 방법
React.js로 작성된 간단한 클라이언트입니다. Jquery에서 AJAX를 통해 API를 호출하고 있습니다. React 사이트가 작동하므로 그 사실을 알지 못합니다. Jquery API 호출은 시도 1에서 확인한대로 작동합니다. 다음은 호출 방법입니다.

    var apiUrl = "http://andrewgodfroyportfolioapi.azurewebsites.net/api/Authentication";
    //alert(username + "|" + password + "|" + apiUrl);
    $.ajax({
        url: apiUrl,
        type: "POST",
        data: {
            username: username,
            password: password
        },
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function (response) {
            var authenticatedUser = JSON.parse(response);
            //alert("Data Loaded: " + authenticatedUser);
            if (onComplete != null) {
                onComplete(authenticatedUser);
            }
        },
        error: function (xhr, status, error) {
            //alert(xhr.responseText);
            if (onComplete != null) {
                onComplete(xhr.responseText);
            }
        }
    });

내가 시도한 것


시도 1- ‘적절한’방법

https://docs.microsoft.com/en-us/aspnet/core/security/cors

Microsoft 웹 사이트의이 자습서를 따라 T를 시작했습니다. Startup.cs에서 전역으로 활성화하고 모든 컨트롤러에서 설정하고 모든 작업에서 시도하는 세 가지 옵션을 모두 시도했습니다.

이 방법에 따라 교차 도메인이 작동하지만 단일 컨트롤러 (POST to AccountController)의 단일 작업에서만 작동합니다. 다른 모든 경우에 Microsoft.AspNetCore.Cors미들웨어는 헤더 설정을 거부합니다.

Microsoft.AspNetCore.CorsNUGET을 통해 설치 했으며 버전은1.1.2

다음은 Startup.cs에서 설정하는 방법입니다.

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        // Add Cors
        services.AddCors(o => o.AddPolicy("MyPolicy", builder =>
        {
            builder.AllowAnyOrigin()
                   .AllowAnyMethod()
                   .AllowAnyHeader();
        }));

        // Add framework services.
        services.AddMvc();
        services.Configure<MvcOptions>(options =>
        {
            options.Filters.Add(new CorsAuthorizationFilterFactory("MyPolicy"));
        });

        ...
        ...
        ...
    }

    // This method gets called by the runtime. Use this method to configure 
    //the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env,
    ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole(Configuration.GetSection("Logging"));
        loggerFactory.AddDebug();

        // Enable Cors
        app.UseCors("MyPolicy");

        //app.UseMvcWithDefaultRoute();
        app.UseMvc();

        ...
        ...
        ...
    }

보시다시피, 나는 지시대로 모든 것을하고 있습니다. MVC 앞에 Cors를 두 번 추가하고 작동하지 않을 때 [EnableCors("MyPolicy")]모든 컨트롤러를 배치하려고 시도했습니다.

[Route("api/[controller]")]
[EnableCors("MyPolicy")]
public class AdminController : Controller

시도 2-무차별 강제

https://andrewlock.net/adding-default-security-headers-in-asp-net-core/

이전 시도에서 몇 시간 동안 시도한 후 헤더를 수동으로 설정하여 모든 응답에서 강제로 실행하도록 시도하여 무차별 적으로 시도하려고 생각했습니다. 이 튜토리얼을 따라 모든 응답에 헤더를 수동으로 추가하는 방법에 대해이 작업을 수행했습니다.

이들은 내가 추가 한 헤더입니다

.AddCustomHeader("Access-Control-Allow-Origin", "*")
.AddCustomHeader("Access-Control-Allow-Methods", "*")
.AddCustomHeader("Access-Control-Allow-Headers", "*")
.AddCustomHeader("Access-Control-Max-Age", "86400")

이것들은 내가 시도한 다른 헤더입니다.

.AddCustomHeader("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE")
.AddCustomHeader("Access-Control-Allow-Headers", "content-type, accept, X-PINGOTHER")
.AddCustomHeader("Access-Control-Allow-Headers", "X-PINGOTHER, Host, User-Agent, Accept, Accept: application/json, application/json, Accept-Language, Accept-Encoding, Access-Control-Request-Method, Access-Control-Request-Headers, Origin, Connection, Content-Type, Content-Type: application/json, Authorization, Connection, Origin, Referer")

이 방법을 사용하면 크로스 사이트 헤더가 올바르게 적용되고 개발자 콘솔과 Postman에 표시됩니다. 그러나 문제는 Access-Control-Allow-Origin수표를 통과하는 동안 웹 브라우저가 (내가 믿는) Access-Control-Allow-Headers진술 에 히스토리를 던진다는 것입니다415 (Unsupported Media Type)

따라서 무차별 강제 방법도 작동하지 않습니다


드디어

누구 든지이 일을하고 손을 빌려 줄 수 있습니까, 아니면 올바른 방향으로 나를 가리킬 수 있습니까?


편집하다

따라서 API 호출을 통과하려면 JQuery 사용을 중단하고 순수 자바 스크립트 XMLHttpRequest형식으로 전환해야했습니다 .

시도 1

나는 그럭저럭 Microsoft.AspNetCore.Cors, MindingData의 대답에 따라 대한 작업은이를 제외 Configure퍼팅 방법 app.UseCors전에 app.UseMvc.

또한 options.AllowAnyOrigin()와일드 카드 지원을 위해 Javascript API 솔루션과 혼합 될 때도 작동하기 시작했습니다.

시도 2

그래서 와일드 카드 Access-Control-Allow-Origin가 작동하지 않는다는 유일한 예외를 제외하고는 시도 2 ​​(브 루트 강제)가 작동 하도록했습니다. 따라서 액세스 할 수있는 도메인을 수동으로 설정해야합니다.

이 WebAPI가 모든 사람에게 널리 개방되기를 원하기 때문에 이상적이지는 않지만 분명히 별도의 사이트에서 작동합니다.

app.UseSecurityHeadersMiddleware(new SecurityHeadersBuilder()
    .AddDefaultSecurePolicy()
    .AddCustomHeader("Access-Control-Allow-Origin", "http://localhost:3000")
    .AddCustomHeader("Access-Control-Allow-Methods", "OPTIONS, GET, POST, PUT, PATCH, DELETE")
    .AddCustomHeader("Access-Control-Allow-Headers", "X-PINGOTHER, Content-Type, Authorization"));



답변

매우 간단한 CORS 정책 (XXX 도메인의 모든 요청 허용)이 있으므로 그렇게 복잡하게 만들 필요는 없습니다. 다음을 먼저 시도하십시오 (CORS의 매우 기본적인 구현).

아직 CORS nuget 패키지를 설치하지 않은 경우 설치하십시오.

Install-Package Microsoft.AspNetCore.Cors

startup.cs의 ConfigureServices 메소드에서 CORS 서비스를 추가하십시오.

public void ConfigureServices(IServiceCollection services)
{
    services.AddCors(); // Make sure you call this previous to AddMvc
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}

그런 다음 startup.cs의 Configure 메소드에서 다음을 추가하십시오.

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    // Make sure you call this before calling app.UseMvc()
    app.UseCors(
        options => options.WithOrigins("http://example.com").AllowAnyMethod()
    );

    app.UseMvc();
}

이제 가자. 정책은 다른 작업 (예 : 다른 호스트 또는 다른 헤더)에 대해 다른 정책을 원할 때 사용됩니다. 간단한 예제에서는 실제로 필요하지 않습니다. 이 간단한 예제부터 시작하여 필요에 따라 조정하십시오.

추가 자료 : http://dotnetcoretutorials.com/2017/01/03/enabling-cors-asp-net-core/


답변

  • 에서 ConfigureServices 추가 services.AddCors(); services.AddMvc () 전에;

  • Configure 에서 UseCors 추가

     app.UseCors(builder => builder
         .AllowAnyOrigin()
         .AllowAnyMethod()
         .AllowAnyHeader());   
     app.UseMvc();
    

요점은 app.UseCors전에 추가하는 것 app.UseMvc()입니다.

MVC 파이프 라인이 제어를 요청하고 요청을 종료하기 전에 미들웨어가 시작되도록 MVC 전에 CORS 기능을 선언해야합니다.

위의 방법이 작동하면 API 호출을 수락하고 API를 다른 사람에게 공개하지 않도록 특정 ORIGIN을 구성하도록 변경할 수 있습니다

public void ConfigureServices(IServiceCollection services)
{
    services.AddCors(options => options.AddPolicy("ApiCorsPolicy", builder =>
    {
        builder.WithOrigins("http://localhost:4200").AllowAnyMethod().AllowAnyHeader();
    }));

    services.AddMvc();
}

configure 메소드에서 방금 작성한 정책을 사용하도록 CORS에 지시하십시오.

app.UseCors("ApiCorsPolicy");
app.UseMvc();

방금이 주제에 대한이 소형 기사를 발견했습니다-https:
//dzone.com/articles/cors-in-net-core-net-core-security-part-vi


답변

나를 위해 일한 내 자신의 미들웨어 클래스를 만들었습니다. .net 코어 미들웨어 클래스에 문제가 있다고 생각합니다.

public class CorsMiddleware
{
    private readonly RequestDelegate _next;

    public CorsMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public Task Invoke(HttpContext httpContext)
    {
        httpContext.Response.Headers.Add("Access-Control-Allow-Origin", "*");
        httpContext.Response.Headers.Add("Access-Control-Allow-Credentials", "true");
        httpContext.Response.Headers.Add("Access-Control-Allow-Headers", "Content-Type, X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Date, X-Api-Version, X-File-Name");
        httpContext.Response.Headers.Add("Access-Control-Allow-Methods", "POST,GET,PUT,PATCH,DELETE,OPTIONS");
        return _next(httpContext);
    }
}

// Extension method used to add the middleware to the HTTP request pipeline.
public static class CorsMiddlewareExtensions
{
    public static IApplicationBuilder UseCorsMiddleware(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<CorsMiddleware>();
    }
}

그리고 startup.cs에서 이런 식으로 사용했습니다.

app.UseCorsMiddleware();


답변

필자의 경우 getMindingData의 답변에 따라 요청 만 잘 작동합니다. 다른 유형의 요청의 경우 다음을 작성해야합니다.

app.UseCors(corsPolicyBuilder =>
   corsPolicyBuilder.WithOrigins("http://localhost:3000")
  .AllowAnyMethod()
  .AllowAnyHeader()
);

추가하는 것을 잊지 마십시오 .AllowAnyHeader()


답변

user8266077답변 을 확장 하기 위해 .NET Core 2.1-preview에서 유스 케이스에 대한 프리 플라이트 요청 에 대한 OPTIONS 응답을 여전히 제공해야한다는 것을 알았습니다 .

// https://stackoverflow.com/a/45844400
public class CorsMiddleware
{
  private readonly RequestDelegate _next;

  public CorsMiddleware(RequestDelegate next)
  {
    _next = next;
  }

  public async Task Invoke(HttpContext context)
  {
    context.Response.Headers.Add("Access-Control-Allow-Origin", "*");
    context.Response.Headers.Add("Access-Control-Allow-Credentials", "true");
    // Added "Accept-Encoding" to this list
    context.Response.Headers.Add("Access-Control-Allow-Headers", "Content-Type, X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Accept-Encoding, Content-Length, Content-MD5, Date, X-Api-Version, X-File-Name");
    context.Response.Headers.Add("Access-Control-Allow-Methods", "POST,GET,PUT,PATCH,DELETE,OPTIONS");
    // New Code Starts here
    if (context.Request.Method == "OPTIONS")
    {
      context.Response.StatusCode = (int)HttpStatusCode.OK;
      await context.Response.WriteAsync(string.Empty);
    }
    // New Code Ends here

    await _next(context);
  }
}

Startup.cs에서 미들웨어를 활성화했습니다.

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
  app.UseMiddleware(typeof(CorsMiddleware));
  // ... other middleware inclusion such as ErrorHandling, Caching, etc
  app.UseMvc();
}


답변

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
       app.UseCors(builder => builder
                .AllowAnyHeader()
                .AllowAnyMethod()
                .SetIsOriginAllowed((host) => true)
                .AllowCredentials()
            );
    }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddCors();
    }


답변

나는 DAYS를 위해 이것으로 고투하고 있었다.

app.UseCors(CORS_POLICY);TOP 으로 이동 하여 마침내 작동하게되었습니다 Configure().

https://weblog.west-wind.com/posts/2016/sep/26/aspnet-core-and-cors-gotchas

MVC가 요청을 완료하기 전에 헤더를 적용해야하므로> MVC 전에 CORS 기능을 선언해야합니다.

<= 내 앱이 전화하지 않았지만 맨 위로 UseMVC()이동 UseCors()하면 문제가 해결되었습니다.

또한:

  • Microsoft.AspNetCore.Cors이전에는 .Net Core 2 이하에서 필요한 NuGet 패키지였습니다. 이제 .Net Core 3 이상의 Microsoft.AspNetCore에 자동으로 포함됩니다.
  • builder.AllowAnyOrigin().AllowCredentials()CORS 옵션은 이제 닷넷 코어 3 이상에서 상호 배타적
  • CORS 정책에 따라 Angular에서 서버를 호출해야합니다 https. .Net Core 서버의 CORS 구성에 관계없이 http URL에서 CORS 오류가 발생하는 것 같습니다. 예를 들어 http://localhost:52774/api/ContactsCORS 오류가 발생합니다. https://localhost:44333/api/Contacts작동 하도록 URL을 변경하기 만하면 됩니다.

추가 사항 :

필자의 경우 CORS는 app.UseCors()위로 이동할 때까지 작동하지 않습니다 app.UseEndpoints(endpoints => endpoints.MapControllers()).