是否有人为仅适用于ASP.NET Core WebAPI的项目(没有Mvc)的Sustainsys Saml2库提供了工作示例,没有ASP身份标识,还有什么更重要? 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);
});
在AccountContoller.cs中(我尝试遵循how to implement google login in .net core without an entityframework provider中所述的类似情况):
[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);
}
TLDR:在我的ASP.NET Core WebApi项目中配置SAML看起来不错,并且在日志中检查了正确的声明后,我获得了成功响应。我不知道如何提取此数据(返回URL错误或我的回调方法应该工作不同)。同样,令人困惑的是为什么从SSO登录页面成功重定向被视为“未经请求”,也许是问题所在?
感谢您的帮助
答案 0 :(得分:3)
对于在此问题上仍需要帮助的任何人,我将一个完整的工作示例推送到github,该示例使用.Net Core WebAPI作为后端,并使用Angular客户端使用WebAPI。您可以在此处找到示例:
答案 1 :(得分:0)
事实证明,我遇到的各种错误是由于我的解决方案托管在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
它修复了所有问题,其中包括:
因此很难找到它,因为代码引发的异常无法指出发生了什么(而未经请求的SSO调用使我认为SSO提供程序配置错误)。直到我拆解Saml2程序包并逐个尝试各种代码段时,我才终于获得了适当的异常(关于密钥链)的知识,这反过来又引出了我有关aspnet数据保护的文章。
我提供了这个答案,以便可能会对某人有所帮助,并为适当的受众群体添加了docker标签。