ASP.Net Core尽可能多地重用默认oauth2代码



我不得不从后台服务连接到第三方oauth2,我想知道如何在不编写太多自己的代码的情况下做到这一点。

情况:我有一个ASP。NET Core 3.1应用程序,具有简单的cookie身份验证,需要完成一些片段:

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
{
...
options.LoginPath = "/Authentication/Login";
...
});

在AuthenticationController 的登录操作中

...
var id = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme);
id.AddClaim(new Claim(ClaimTypes.NameIdentifier, "some user identifier"));
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(id))
...

到目前为止,一切都很好。

现在我想连接到第三方的API,该第三方正在使用oauth2进行一些应用程序活动(例如同步应用程序数据(。现在我可以编写自己的oauth2身份验证逻辑了,但如果ASP中已经有了,我为什么要写呢。NET核心框架。所以我想到了以下几点:

AddOAuth扩展AddAuthentication,用正确的sheme调用ChallengeResult。身份验证后,在回调中,将访问令牌保存在内存中,将刷新令牌保存在安全的持久存储中,以便应用程序稍后可以在某些后台任务(IHostedService(中与HTTP客户端结合使用。

所以我扩展了AddAuthentication:

.AddOAuth("My-Scheme", options =>
{
options.ClientId = "a client id";
options.ClientSecret = "a client secret";
options.CallbackPath = new PathString("/signin-name-of-third-party");
// Endpoint configs
...
});

AuthenticationController旁边有一个带有Connect操作的IntergrationController,返回的代码如下:

var redirectUrl  = ...
var properties = new AuthenticationProperties { RedirectUri = redirectUrl };
return new ChallengeResult("My-Scheme", properties);

使用cookie身份验证登录(IntergrationController需要身份验证(并调用Connect操作后,会将我重定向到第三方。输入凭据后,我将按预期重定向回自己的应用程序。我没想到的是,当前用户(HttpContext.User(被第三方的用户替换了(例如,通过将其添加为ClaimsIdentity(,这破坏了应用程序,因为名称标识符也被第三方向的用户替换,该用户与我的应用程序中的任何用户都不匹配。

这里少了什么?为什么要更换HttpContext.User?我该如何预防?

此外,如果你对此有其他想法或建议,请分享。

谢谢!

如果我正确理解您的问题,您可能需要两个cookie/登录方案:一个用于您自己的身份,另一个用于第三方身份。当您添加OAuth方案时,将其设置为使用第三方cookie方案登录,以便第三方身份持久存在cookie中,该cookie不会取代您的应用程序的cookie:

services.AddAuthentication()
.AddCookie("cookie-your-app")
.AddCookie("cookie-third-party")
.AddOAuth("third-party", opt =>
{
opt.SignInScheme = "cookie-third-party";
});

如果你需要为一个方法恢复两个身份,你可以使用授权策略来组合两个cookie方案:

services.AddAuthorization(opt =>
{
opt.AddPolicy("combined-cookies", builder =>
{
builder.AddAuthenticationSchemes("cookie1", "cookie2");
builder.RequireAuthenticatedUser();
});
});

因此,当您授权使用该策略时,您应该在HttpContext.User.Identities:中看到两个身份

[Authorize("combined-cookies")]
public IActionResult Privacy()
{
// Two identities here
var identities = HttpContext.User.Identities;
return View();
}

对于需要任意一个的端点,请相应地使用Authorize属性从所需cookie中恢复身份。

最新更新