CORS 错误:LinkedIn 身份验证; .NET Core 5 REST API
Posted
技术标签:
【中文标题】CORS 错误:LinkedIn 身份验证; .NET Core 5 REST API【英文标题】:CORS Error: LinkedIn Authentication; .NET Core 5 REST Api 【发布时间】:2021-10-16 03:22:40 【问题描述】:技术栈
使用 .NET CORE React 模板 1 个 IIS 网站 应用程序池(v4 集成) 80 端口-
单击注册按钮,调用注册组件。
useEffect() 中的组件,使用 Axios 调用“/login URL”
C# Map("/login") 被称为使用 LinkedIn 进行身份验证的挑战
然后返回 CORS 错误
错误 Snapshot 1 of 5 Snapshot 2 of 5; Snapshot 3 of 5; Snapshot 4 of 5; Snapshot 5 of 5
反应代码
const url = `/login`;
const headers =
'Content-Type': 'text/html'
axios(
method: 'get',
url: url,
headers: headers
)
.then((response) => ...)
.catch((error: Error | AxiosError) => ...);
C# 代码 - 链接身份验证、Cookie、CORS 中间件
Start.cs - ConfigureServices()
public void ConfigureServices(IServiceCollection services)
#region AddAuthentication, AddLinkedIn, AddCookie
services.AddAuthentication()
.AddLinkedIn(o =>
IConfigurationSection linkedinAuthNSection =
Configuration.GetSection("Authentication:Linkedin");
o.ClientId = linkedinAuthNSection["ClientId"];
o.ClientSecret = linkedinAuthNSection["ClientSecret"];
)
.AddCookie(o =>
o.LoginPath = "/login";
o.LogoutPath = "/logout";
);
#endregion
#region Global CORS Policy Declaration
services.AddCors(o =>
o.AddDefaultPolicy(builder =>
builder.AllowAnyMethod()
.AllowAnyHeader()
.AllowAnyOrigin()
);
);
#endregion
services.AddControllersWithViews();
// In production, the React files will be served from this directory
services.AddSpaStaticFiles(configuration =>
configuration.RootPath = "client-app/build";
);
Start.cs - Configure()
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
else
app.UseExceptionHandler("/Error");
#region Map/login
app.Map("/login", builder =>
builder.Run(async context =>
var properties = new AuthenticationProperties() RedirectUri = "/" ;
await context.ChallengeAsync("LinkedIn", properties);
);
);
#endregion
#region Map/logout
app.Map("/logout", builder =>
builder.Run(async context =>
await context.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
context.Response.Redirect("/");
);
);
#endregion
app.UseStaticFiles();
app.UseSpaStaticFiles();
app.UseRouting();
app.UseCors();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
endpoints.MapControllerRoute(
name: "default",
pattern: "controller/action=Index/id?");
);
app.UseSpa(spa =>
spa.Options.SourcePath = Path.Join(env.ContentRootPath, "client-app");
if (env.IsDevelopment())
spa.Options.StartupTimeout = TimeSpan.FromSeconds(240);
spa.UseReactDevelopmentServer(npmScript: "start");
);
【问题讨论】:
★ 我认为缺少的是如何将属性 [EnableCors] 链接到以下路径的属性:app.Map("/login", builder => MapLogin(builder); );
究竟是什么是 cors 错误? cors 错误在指出错误方面非常直接和准确
@KevinB 在开发工具中,它只在网络选项卡 (1) 中显示 CORS。 React 应用程序,在 IIS 中定义为端口 80 的“网站”。 (2) .NET Core REST API 定义为上述“网站”中的“应用程序”,位于不同的物理位置。 (3) React 向 REST API 发出“登录”请求。 (4) “/login”请求向LinkedIn发出一个Authentication Challenge。 (5) 然后我收到一个 CORS 错误
你用什么浏览器提供的信息这么少?
您应该将错误文本放在您的问题中。你被否决了,因为它不存在。谷歌根据其中的文本链接到问题,并且您链接以生成错误是完全短暂的,因为如果它得到修复,它将消失。还有其他一些小事,但这是大事。您的标题也没有帮助,也应该进行编辑以反映错误消息。如何提问->***.com/help/how-to-ask
【参考方案1】:
终于搞定了!
在尝试理解、理解内化之后,我做出了 2 个重大改变。感谢 Chrome Dev Tools 的黄色警告符号⚠,让我可以this article 并更改解决方案的 1。
更改 1
将上述示例代码的主要 sn-ps 应用到我的 React SPA .NET Core 项目中
删除了允许管道路径分支的地图中间件 (app.Map("/login")。
支持 .NET 控制器/操作。
但更具体地说,只是 Action,因为 "/login" 被添加到 URL 的路径中,这使得很难接受成功的登录。
更改 2
仅针对身份验证 UI 交互丢弃 Axios 调用,因为 LinkedIn 不支持它。 LinkedIn OAuth redirect login returning "No 'Access-Control-Allow-Origin' header is present on the requested resource" error
赞成使用 HTML href。
Authentication.cs
//[Route("[controller]/[action]")]
[Route("[action]")]
public class AuthenticationController : Controller
[HttpGet]
public IActionResult Register(string authType = "LinkedIn")
return Challenge(new AuthenticationProperties() RedirectUri = "/" );
[HttpGet]
public IActionResult Login(string authType = "LinkedIn")
return Challenge(new AuthenticationProperties() RedirectUri = "/" );
[HttpGet]
public IActionResult Logout()
return SignOut();
Start.cs ConfigureServices()
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
services.AddRazorPages();
services.AddAuthentication(o =>
o.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
o.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
o.DefaultChallengeScheme = "LinkedIn";
)
.AddCookie()
.AddOAuth("LinkedIn", o =>
o.CorrelationCookie.HttpOnly = true;
o.CorrelationCookie.SameSite = SameSiteMode.Lax;
var linkedInSection = Configuration.GetSection("Authentication:LinkedIn");
o.ClientId = linkedInSection.GetSection("ClientId").Get<string>();
o.ClientSecret = linkedInSection.GetSection("ClientSecret").Get<string>();
o.CallbackPath = new PathString(linkedInSection.GetSection("CallbackPath").Get<string>());
o.AuthorizationEndpoint = linkedInSection.GetSection("AuthorizationEndpoint").Get<string>();
o.TokenEndpoint = linkedInSection.GetSection("TokenEndpoint").Get<string>();
o.UserInformationEndpoint = linkedInSection.GetSection("UserInformationEndpoint").Get<string>();
o.Scope.Add("r_liteprofile");
o.Scope.Add("r_liteprofile");
o.Events = new OAuthEvents
OnCreatingTicket = async context =>
var request = new HttpRequestMessage(HttpMethod.Get, context.Options.UserInformationEndpoint);
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", context.AccessToken);
var response = await context.Backchannel.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, context.HttpContext.RequestAborted);
response.EnsureSuccessStatusCode();
var json = JsonDocument.Parse(await response.Content.ReadAsStringAsync());
context.RunClaimActions(json.RootElement);
;
);
Start.cs Configure()
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
else
app.UseExceptionHandler("/Error");
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseEndpoints(endpoints =>
endpoints.MapControllers();
endpoints.MapRazorPages();
endpoints.MapControllerRoute(
name: "default",
pattern: "controller/action=Index/id?");
);
【讨论】:
【参考方案2】:在您的 Chrome 浏览器中,尝试从 Chrome 网上商店安装一个名为 Access control Allow Origin 的扩展程序。并打开该扩展程序的选项或设置页面,并在文本框中输入您的本地主机地址,如下所示:https://localhost:80 在你的情况下
我曾经遇到过这个问题,这个扩展对我有用..
【讨论】:
安装浏览器扩展是解决 cors 错误的一种非常糟糕的方法。 @igmani 不确定我们是否要走那条路,因为我们不能强迫我们的客户遵循该流程以上是关于CORS 错误:LinkedIn 身份验证; .NET Core 5 REST API的主要内容,如果未能解决你的问题,请参考以下文章
在 .NET Core 3.1 中添加窗口身份验证后出现 Cors 错误
发送身份验证承载令牌时出现 Cors 策略错误 - node.js(谷歌云功能)
从 localhost 到 rest api 的身份验证结果 CORS 错误
使用护照进行 Facebook 身份验证的 Node+react 应用程序中的 CORS 错误