我可以在 ASP.NET Core 3 中组合来自两个身份验证方案的身份吗?
Can I Combine Identities from two Authentication Schemes in ASP.NET Core 3?
我有一个 Web 应用程序,它利用我们组织的 CAS 服务器进行身份验证。我目前正在为此应用程序开发与 DocuSign 的集成。用户将首先访问我们的网站并使用 CAS 登录。然后,他们可以转到应用程序的 DocuSign 区域,登录 DocuSign,然后执行与 DocuSign API 绑定的一些功能。这些部分中的每一个都在我的应用程序中正常工作。
我目前的问题是我无法同时访问 HttpContext 中的两个身份。我需要 CAS 身份来确定用户行为和对某些功能的访问。我需要 DocuSign Identity 来获取启用 API 调用所需的值。在Startup.cs
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.LoginPath = new PathString("/Account/Login");
})
.AddCAS(options =>
{
options.CasServerUrlBase = Configuration["CasBaseUrl"];
options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddOAuth("DocuSign", options ->
{
//necessary DocuSign options
});
我有一个 HomeController,它使用 Authorize 属性并正确地需要 CAS 才能访问。我可以从 CAS 身份正确访问声明。我有一个 DocusignController,我在其中使用 Authorize(AuthenticationSchemes = "DocuSign")。适用于此控制器的 ActionFilter 显示 DocuSign 身份正确通过。不幸的是,没有附加 CAS 标识,所以我无法检查诸如管理员权限之类的东西。我检查了 cookie,发现当我在不同的身份验证方案之间切换时,.AspNetCore.Cookies 值会发生变化。
解决方案的一个尝试是将 DocusignController 更改为具有 Authorize(AuthenticationSchemes = "DocuSign, CAS") 作为其属性。这似乎是 'or' 而不是 'and'两种方案。如果 CAS 是最新的方案,那么 CAS 身份就是在我的 ActionFilter 中看到的那个。DocuSign 也是如此。
另一个尝试是创建我自己的 AuthenticationHandler 来组合两个身份。附加到上面的 AddAuthentication:
.AddScheme<CombinedSchemeOptions, CombinedHandler>
("Combined", op => { });
然后,在此 CombinedHandler 中:
protected async override Task<AuthenticateResult> HandleAuthenticateAsync()
{
var CasResult = await Context.AuthenticateAsync("CAS");
if(CasResult?.Principal != null)
{
principal.AddIdentities(CasResult.Principal.Identities);
}
var DSResult = await Context.AuthenticateAsync("DocuSign");
if(DSResult?.Principal != null)
{
principal.AddIdentities(DSResult.Principal.Identities);
}
var ticket = new AuthenticationTicket(principal, "Combined");
return AuthenticateResult.Success(ticket);
}
这似乎与以前的行为方式相同。我最近使用的方案,在进入组合方案后,将给出一个带有身份的成功结果,而另一个结果将 return 失败。
我可以在HttpContext.User中同时拥有这两个身份吗?我是否可以将两个身份的声明合并为一个并传递给它?
进一步的研究和修补使我找到了解决方案。首先,我发现我需要两种身份验证方案来写入单独的 cookie。然后我确保 DocuSign 方案使用新的 cookie 作为其 SignInScheme。
.AddCookie("DSCookie")
.AddOAuth("DocuSign", options =>
{
options.SignInScheme = "DSCookie";
//further DocuSign options
}
我还了解到,Authorize 标签用作 OR 语句(如果您有 CAS 或 DocuSign,则您有权执行此操作),但它会传递该方案允许的所有有效身份(您有 CAS 和你有 DocuSign 吗?带上两个身份)。因此,我的解决方案的第二部分只有一个操作需要 DocuSign 身份验证,从而引发必要的质询。然后,我转到具有两种身份验证方案的操作,并且两种身份都正确携带。
编辑:根据 Dmitriy 的要求进行详细说明
[Authorize(AuthenticationSchemes = "DocuSign")]
public ActionResult Index()
{
return RedirectToAction("Control");
}
[Authorize(AuthenticationSchemes = "DocuSign,CAS")]
public ActionResult Control()
{
//relevant code
}
我单击 link 以转到“索引”操作。由于我目前没有有效的 DocuSign 身份,它会执行必要的提示并将我带到登录屏幕。如果我 link 直接进入控制,身份验证会看到我目前拥有有效的 CAS 身份,因此会批准我的访问,即使我还没有 DocuSign 身份。
登录后,当我到达索引功能时,目前只有DocuSign Identity可用。然后我重定向到 Control。该功能验证我至少拥有一个指定的身份,授予我访问权限,并传递我目前拥有的任何列出的身份。因此,在 Control 中,我可以从 CAS 和 DocuSign 中获取信息。
我有一个 Web 应用程序,它利用我们组织的 CAS 服务器进行身份验证。我目前正在为此应用程序开发与 DocuSign 的集成。用户将首先访问我们的网站并使用 CAS 登录。然后,他们可以转到应用程序的 DocuSign 区域,登录 DocuSign,然后执行与 DocuSign API 绑定的一些功能。这些部分中的每一个都在我的应用程序中正常工作。
我目前的问题是我无法同时访问 HttpContext 中的两个身份。我需要 CAS 身份来确定用户行为和对某些功能的访问。我需要 DocuSign Identity 来获取启用 API 调用所需的值。在Startup.cs
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options =>
{
options.LoginPath = new PathString("/Account/Login");
})
.AddCAS(options =>
{
options.CasServerUrlBase = Configuration["CasBaseUrl"];
options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddOAuth("DocuSign", options ->
{
//necessary DocuSign options
});
我有一个 HomeController,它使用 Authorize 属性并正确地需要 CAS 才能访问。我可以从 CAS 身份正确访问声明。我有一个 DocusignController,我在其中使用 Authorize(AuthenticationSchemes = "DocuSign")。适用于此控制器的 ActionFilter 显示 DocuSign 身份正确通过。不幸的是,没有附加 CAS 标识,所以我无法检查诸如管理员权限之类的东西。我检查了 cookie,发现当我在不同的身份验证方案之间切换时,.AspNetCore.Cookies 值会发生变化。
解决方案的一个尝试是将 DocusignController 更改为具有 Authorize(AuthenticationSchemes = "DocuSign, CAS") 作为其属性。这似乎是 'or' 而不是 'and'两种方案。如果 CAS 是最新的方案,那么 CAS 身份就是在我的 ActionFilter 中看到的那个。DocuSign 也是如此。
另一个尝试是创建我自己的 AuthenticationHandler 来组合两个身份。附加到上面的 AddAuthentication:
.AddScheme<CombinedSchemeOptions, CombinedHandler>
("Combined", op => { });
然后,在此 CombinedHandler 中:
protected async override Task<AuthenticateResult> HandleAuthenticateAsync()
{
var CasResult = await Context.AuthenticateAsync("CAS");
if(CasResult?.Principal != null)
{
principal.AddIdentities(CasResult.Principal.Identities);
}
var DSResult = await Context.AuthenticateAsync("DocuSign");
if(DSResult?.Principal != null)
{
principal.AddIdentities(DSResult.Principal.Identities);
}
var ticket = new AuthenticationTicket(principal, "Combined");
return AuthenticateResult.Success(ticket);
}
这似乎与以前的行为方式相同。我最近使用的方案,在进入组合方案后,将给出一个带有身份的成功结果,而另一个结果将 return 失败。
我可以在HttpContext.User中同时拥有这两个身份吗?我是否可以将两个身份的声明合并为一个并传递给它?
进一步的研究和修补使我找到了解决方案。首先,我发现我需要两种身份验证方案来写入单独的 cookie。然后我确保 DocuSign 方案使用新的 cookie 作为其 SignInScheme。
.AddCookie("DSCookie")
.AddOAuth("DocuSign", options =>
{
options.SignInScheme = "DSCookie";
//further DocuSign options
}
我还了解到,Authorize 标签用作 OR 语句(如果您有 CAS 或 DocuSign,则您有权执行此操作),但它会传递该方案允许的所有有效身份(您有 CAS 和你有 DocuSign 吗?带上两个身份)。因此,我的解决方案的第二部分只有一个操作需要 DocuSign 身份验证,从而引发必要的质询。然后,我转到具有两种身份验证方案的操作,并且两种身份都正确携带。
编辑:根据 Dmitriy 的要求进行详细说明
[Authorize(AuthenticationSchemes = "DocuSign")]
public ActionResult Index()
{
return RedirectToAction("Control");
}
[Authorize(AuthenticationSchemes = "DocuSign,CAS")]
public ActionResult Control()
{
//relevant code
}
我单击 link 以转到“索引”操作。由于我目前没有有效的 DocuSign 身份,它会执行必要的提示并将我带到登录屏幕。如果我 link 直接进入控制,身份验证会看到我目前拥有有效的 CAS 身份,因此会批准我的访问,即使我还没有 DocuSign 身份。
登录后,当我到达索引功能时,目前只有DocuSign Identity可用。然后我重定向到 Control。该功能验证我至少拥有一个指定的身份,授予我访问权限,并传递我目前拥有的任何列出的身份。因此,在 Control 中,我可以从 CAS 和 DocuSign 中获取信息。