【问题标题】:.Net Core 2.0 REST API w/ Windows Auth - Preflight responding with 401 Unauthorized.Net Core 2.0 REST API w/Windows Auth - Preflight 响应 401 Unauthorized
【发布时间】:2018-07-24 05:26:37
【问题描述】:

我正在使用 .NET Core 2.0 和 Angular 4 在本地创建网页。我能够让我的前端成功提交 GET 请求,但不能提交 POST。我已经尝试了所有启用 CORS 和 Windows 身份验证的方法,但我总是收到未经授权的错误。我在这里错过了什么才能通过飞行前?我假设它与 Windows 身份验证有关,但我发现的所有内容都只是说我需要 'withCredentials:true' 标头选项。

角度服务

const httpOptions = {
  headers: new HttpHeaders({
    'Content-Type':  'application/json'
  }),
  withCredentials: true
};

@Injectable()
export class TestService {

  constructor(private http: HttpClient) { }

  private baseURL = 'http://localhost:58214/api/{insert_app_name_here}';

  getAllRules() {
    console.log('Getting rules');
    return this.http.get<RuleItem>(this.baseURL).subscribe(res => {
      console.log(res);
    });
  }

  createNewRule(ri: RuleItem) {
    return this.http.post<RuleItem>(this.baseURL, JSON.stringify(ri), httpOptions).subscribe(res => {
      console.log(res);
    }, err => {
      console.log('Error occurred: ', err);
    });
  }

}

.NET CORE 2.0 控制器

// [EnableCors("SitePolicy")]
 [Route("api/[controller]")]
    public class TestController : Controller
    {

        private readonly RuleContext _context;

        public TestController(RuleContext context)
        {
            _context = context;

        }

        [HttpGet]
        public IEnumerable<RuleItem> GetAll()
        {
            return _context.RuleItems.ToList();
        }

        [HttpGet("{id}", Name = "GetRule")]
        public IActionResult GetById(long id)
        {
            var item = _context.RuleItems.FirstOrDefault(r => r.Id == id);
            if (item == null)
            {
                return NotFound();
            }
            return new ObjectResult(item);
        }

        [HttpPost]
        public IActionResult Create(RuleItem item)
        {

            if (item == null)
            {
                return BadRequest();
            }

            _context.RuleItems.Add(item);
            _context.SaveChanges();

            return CreatedAtRoute("GetTodo", new { id = item.Id }, item);
        }

    }

Startup.cs

 public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {

            /*
            services.AddCors(options =>
            {
                options.AddPolicy("SitePolicy", builder =>
                {
                    builder.AllowAnyOrigin()
                            .AllowAnyOrigin()
                            .AllowAnyMethod()
                            .AllowCredentials();
                });
            });

            services.AddAuthentication(IISDefaults.AuthenticationScheme);*/

            services.AddMvc();

            var connection = @"Server=servername;Database=dbname;Trusted_Connection=true;MultipleActiveResultSets=True;";
            services.AddDbContext<RuleContext>(options => options.UseSqlServer(connection));
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            // app.UseCors("SitePolicy");

            app.UseMvc();
        }
    }

web.config 如果我以编程方式添加了 CORS,不确定是否需要这个,但这是成功摆脱“没有允许来源标头存在”错误的唯一解决方案

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Origin" value="http://localhost:4200" />
        <add name="Access-Control-Allow-Headers" value="Content-Type" />
        <add name="Access-Control-Allow-Methods" value="GET,POST,PUT,DELETE,OPTIONS" />
        <add name="Access-Control-Allow-Credentials" value="true" />
      </customHeaders>
    </httpProtocol>
  </system.webServer>
</configuration>

编辑 - 进行了以下更改:删除了 web.config 文件,添加了全局 CORS 规则。以下是更改:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {


        services.AddCors();

        //services.AddAuthentication(IISDefaults.AuthenticationScheme);

        services.AddMvc();

        var connection = @"Server=server;Database=db;Trusted_Connection=true;MultipleActiveResultSets=True;";
        services.AddDbContext<RuleContext>(options => options.UseSqlServer(connection));
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseCors(builder =>
        {
            builder.AllowAnyOrigin()
                    .AllowAnyOrigin()
                    .AllowAnyMethod()
                    .AllowCredentials();
        });

        app.UseMvc();
    }
}

控制器

 [Route("api/[controller]")]
    public class TestController : Controller
    {

        private readonly RuleContext _context;

        public TestController(RuleContext context)
        {
            _context = context;

        }

        [HttpGet]
        public IEnumerable<RuleItem> GetAll()
        {
            return _context.RuleItems.ToList();
        }

        [HttpGet("{id}", Name = "GetRule")]
        public IActionResult GetById(long id)
        {
            var item = _context.RuleItems.FirstOrDefault(r => r.Id == id);
            if (item == null)
            {
                return NotFound();
            }
            return new ObjectResult(item);
        }

        [HttpPost]
        public IActionResult Create(RuleItem item)
        {

            if (item == null)
            {
                return BadRequest();
            }

            _context.RuleItems.Add(item);
            _context.SaveChanges();

            return CreatedAtRoute("GetTodo", new { id = item.Id }, item);
        }
}

这是我现在收到的错误消息的图像:401 Error

【问题讨论】:

  • 你不需要编辑你的 web.config(你也不需要提供一个,dotnet publish 会自动创建一个)。启用 CORS 只需将 app.UseCors(builder =&gt; builder .AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin().AllowCredentials()) 添加到应用程序管道。
  • 是的,这就是我最初的想法。我已经输入了确切的代码,但它不起作用。我收到“未指定允许来源标头”错误。我尝试使用 AllowAnyOrigin,然后将我的 localhost:4200 明确定义为唯一允许的来源
  • 中间件已经处理好了。您可以通过设置 Origin 标头来使用邮递员测试 CORS。您可能需要禁用邮递员中的设置,因为他可能会覆盖原点。基本上,如果您将原始标头设置为与您的 PC 主机名不同的内容,则应该触发中间件,并且它应该将 CORS 标头添加到响应中。
  • 此外,如果您定义策略名称,您的控制器上应该有 [EnableCors("PolicyName")] 属性。如果你像我告诉你的那样应用它,它没有策略名称,它应该全局应用于你的应用程序,没有任何属性。
  • 你说得对,我想我没有适当地传递令牌。至少这是一次很好的学习经历。我将使用 NTLM 令牌并验证这是问题并将其关闭。非常感谢!

标签: c# angular asp.net-core asp.net-core-2.0


【解决方案1】:

问题最终在于传递 Windows 令牌。未在预检请求中检查令牌,因此失败。

【讨论】:

  • 您能否说明您是如何传递 windows 令牌的?它是否适用于开发环境??
猜你喜欢
  • 2018-02-28
  • 1970-01-01
  • 1970-01-01
  • 2021-06-17
  • 1970-01-01
  • 2017-06-25
  • 2018-04-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多