ASP.NET Core 2.0中LinkedIn OAuth2.0认证的登录/登出路由配置修改
解决ASP.NET Core 2.0中LinkedIn认证的登录/登出路由修改问题
在ASP.NET Core 2.0中,认证系统的API和中间件配置有一些关键变化,我们可以从两个方向修改你的登录/登出路由逻辑,同时还要确保中间件的正确启用:
一、直接更新app.Map方式的路由代码(适配Core 2.0 API)
Core 2.0将HttpContext.Authentication下的方法直接移到了HttpContext本身,所以你需要修改原来的路由代码,同时必须在Configure方法中添加app.UseAuthentication()(这是Core 2.0新增的核心步骤,用来启用认证中间件)。
修改后的完整Configure方法示例:
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { // 先配置其他基础中间件(比如静态文件、错误页等) if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseStaticFiles(); // 必须添加这一行,启用认证中间件(Core 2.0+必填) app.UseAuthentication(); // 登录路由:触发LinkedIn认证挑战 app.Map("/login", builder => { builder.Run(async context => { // 替换Core 1.0的context.Authentication.ChallengeAsync await context.ChallengeAsync("LinkedIn", new AuthenticationProperties() { RedirectUri = "/" }); }); }); // 登出路由:清除认证Cookie并跳转首页 app.Map("/logout", builder => { builder.Run(async context => { // 替换Core 1.0的context.Authentication.SignOutAsync await context.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); context.Response.Redirect("/"); }); }); // 最后配置MVC路由(如果项目使用MVC) app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); }
二、推荐:使用MVC控制器Action处理登录/登出(更符合Core 2.0最佳实践)
如果你的项目已经集成了MVC,更推荐用控制器Action来处理登录和登出,这样逻辑更清晰,也方便后续扩展(比如支持动态跳转URL):
- 创建一个
AccountController:
public class AccountController : Controller { // 处理登录请求,支持自定义跳转地址 public IActionResult Login(string returnUrl = "/") { return Challenge(new AuthenticationProperties { RedirectUri = returnUrl }, "LinkedIn"); } // 处理登出请求,支持自定义跳转地址 public async Task<IActionResult> Logout(string returnUrl = "/") { await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); return Redirect(returnUrl); } }
- 确保你的MVC路由配置正确(比如默认的
/{controller=Home}/{action=Index}/{id?}),这样就可以通过/Account/Login和/Account/Logout访问登录登出功能。
补充:完善OnCreatingTicket事件逻辑
你的代码中OnCreatingTicket事件还未完成,这里补充完整的逻辑(LinkedIn API需要特定请求头才能返回JSON格式数据):
options.Events = new OAuthEvents() { OnCreatingTicket = async context => { // 构造用户信息请求,添加LinkedIn要求的JSON格式头 var request = new HttpRequestMessage(HttpMethod.Get, context.Options.UserInformationEndpoint); request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", context.AccessToken); request.Headers.Add("x-li-format", "json"); // 发送请求并获取用户信息 var response = await context.Backchannel.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, context.HttpContext.RequestAborted); response.EnsureSuccessStatusCode(); // 解析JSON并添加用户Claims var user = JObject.Parse(await response.Content.ReadAsStringAsync()); context.Identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Value<string>("id"))); context.Identity.AddClaim(new Claim(ClaimTypes.Name, user.Value<string>("formatted-name"))); context.Identity.AddClaim(new Claim(ClaimTypes.Email, user.Value<string>("email-address"))); context.Identity.AddClaim(new Claim("urn:linkedin:picture-url", user.Value<string>("picture-url"))); } };
内容的提问来源于stack exchange,提问作者Reza
相关产品推荐
相关产品推荐

