Liz*_*rtu 7 docker asp.net-core asp.net-core-webapi sustainsys-saml2
有没有人有适用于 ASP.NET Core WebAPI 项目(无 Mvc)的 Sustainsys Saml2 库的工作示例,如果没有 ASP Identity,什么更重要?github 上提供的示例强烈依赖于我不需要也不想使用的 MVC 和 SignInManager。
我添加了 Saml2 身份验证,起初它在我的 IdP 上运行良好(我还检查了 Sustainsys 提供的 StubIdP)的前几个步骤,因此:
但是我不知道如何从那里继续并提取用户登录名和其他声明(我的 IdP 还提供了一封电子邮件,它包含在我在日志中确认的 SAML 响应中)。
遵循在网络上找到的一些示例并稍微修改来自 GitHub 的 MVC 示例,我执行了以下操作:
在 Startup.cs 中:
...
.AddSaml2(Saml2Defaults.Scheme,
options =>
{
options.SPOptions.EntityId = new EntityId("...");
options.SPOptions.ServiceCertificates.Add(...));
options.SPOptions.Logger = new SerilogSaml2Adapter();
options.SPOptions.ReturnUrl = new Uri(Culture.Invariant($"https://localhost:44364/Account/Callback?returnUrl=%2F"));
var idp =
new IdentityProvider(new EntityId("..."), options.SPOptions)
{
LoadMetadata = true,
AllowUnsolicitedAuthnResponse = true, // At first /Saml2/Acs page throwed an exception that response was unsolicited so I set it to true
MetadataLocation = "...",
SingleSignOnServiceUrl = new Uri("...") // I need to set it explicitly because my IdP returns different url in the metadata
};
options.IdentityProviders.Add(idp);
});
Run Code Online (Sandbox Code Playgroud)
在 AccountContoller.cs 中(我试图遵循在没有实体框架提供程序的情况下如何在 .net 核心中实现谷歌登录中描述的有点类似的情况):
[Route("[controller]")]
[ApiController]
public class AccountController : ControllerBase
{
private readonly ILog _log;
public AccountController(ILog log)
{
_log = log;
}
[HttpGet("Login")]
[AllowAnonymous]
public IActionResult Login(string returnUrl)
{
return new ChallengeResult(
Saml2Defaults.Scheme,
new AuthenticationProperties
{
// It looks like this parameter is ignored, so I set ReturnUrl in Startup.cs
RedirectUri = Url.Action(nameof(LoginCallback), new { returnUrl })
});
}
[HttpGet("Callback")]
[AllowAnonymous]
public async Task<IActionResult> LoginCallback(string returnUrl)
{
var authenticateResult = await HttpContext.AuthenticateAsync(Constants.Auth.Schema.External);
_log.Information("Authenticate result: {@authenticateResult}", authenticateResult);
// I get false here and no information on claims etc.
if (!authenticateResult.Succeeded)
{
return Unauthorized();
}
// HttpContext.User does not contain any data either
// code below is not executed
var claimsIdentity = new ClaimsIdentity(Constants.Auth.Schema.Application);
claimsIdentity.AddClaim(authenticateResult.Principal.FindFirst(ClaimTypes.NameIdentifier));
_log.Information("Logged in user with following claims: {@Claims}", authenticateResult.Principal.Claims);
await HttpContext.SignInAsync(Constants.Auth.Schema.Application, new ClaimsPrincipal(claimsIdentity));
return LocalRedirect(returnUrl);
}
Run Code Online (Sandbox Code Playgroud)
TLDR:我的 ASP.NET Core WebApi 项目中的 SAML 配置看起来不错,并且我通过在日志中检查的正确声明获得了成功响应。我不知道如何提取这些数据(要么返回 url 错误,要么我的回调方法应该以不同的方式工作)。此外,令人费解的是,为什么从 SSO 登录页面成功重定向被视为“未经请求的”,也许这就是问题所在?
感谢您的帮助
ant*_*tar 11
对于在这个问题上仍然需要帮助的人,我将一个完整的工作示例推送到了 github,它使用 .Net Core WebAPI 作为后端,并使用 WebAPI 的 Angular 客户端。你可以从这里找到这个例子:
https://github.com/hmacat/Saml2WebAPIAndAngularSpaExample
事实证明,我遇到的各种错误是由于我的解决方案托管在docker容器内造成的。这导致内部 aspnet 钥匙串出现一些故障。更多细节可以在这里找到(docker几乎在文章末尾提到):
长话短说,为了让代码正常工作,我只需要添加这些行:
services.AddDataProtection()
.PersistKeysToFileSystem(new DirectoryInfo("/some/volume/outside/docker")); // it needs to be outside container, even better if it's in redis or other common resource
Run Code Online (Sandbox Code Playgroud)
它修复了一切,其中包括:
因此很难找到,因为代码抛出的异常并没有指出发生了什么(并且未经请求的 SSO 调用让我认为 SSO 提供程序配置错误)。只是当我反汇编 Saml2 包并逐一尝试各种代码片段时,我终于遇到了正确的异常(关于钥匙链),这又让我找到了一篇关于 aspnet 数据保护的文章。
我提供这个答案是为了也许它会对某人有所帮助,并且我为适当的受众添加了 docker 标签。
| 归档时间: |
|
| 查看次数: |
4444 次 |
| 最近记录: |