如何在 .net 4.5 中针对 AzureAD 实现 SAML2 身份验证?(使用令牌)

本文关键字:身份验证 SAML2 令牌 实现 AzureAD net | 更新日期: 2023-09-27 18:34:22

我想允许对我的 Web 应用进行 SAML 身份验证,包括针对作为标识提供者的 AzureAD 和 ADFS。(谁能指出我一个很好的教程或演练?到目前为止,我已经生成了SAML请求,从AzureAD返回SAMLP响应,并验证了其签名(包括默认情况下不起作用的SHA256(。

现在我想从中提取信息以验证颁发者并获取用户的电子邮件以识别它们。通过XML手动执行此操作是"可以"的,还是应该使用Saml2SecurityTokenHandler之类的类?它们看起来应该可以解决问题,但我发现很难理解所需的所有配置以及是否有必要从安全角度使用此类类。

我的应用是多租户的,因此我需要代码而不是配置来处理 Saml,因为不同的租户将使用不同的身份验证选项。

这个博客说不要使用ConfigurationBasedIssuerNameRegistry,而是指向[ValidatingIssuerNameRegistry][3]。好的,这似乎适合我的方案。

在这个问题中,有一些代码可以以编程方式配置受信任的颁发者,因此我可以调整为使用 ValidatingIssuerNameRegistry,然后大概可以使用 tokenHandlers 从 SAMLP 响应中读取Assertion,然后提取包括名称(电子邮件(在内的声明。但是,从哪里获取要从 AzureAD 元数据传递给它的指纹和名称?使用这些类而不是自己解析响应的价值究竟是什么?绝对感觉使用库是正确的做法,但是WIF的复杂性以及缺乏有关执行此操作的演练文章使得除了那些深入身份世界的人之外,感觉不合适。

我的猜测是,如果我已经在本地存储了证书来验证 SAML 响应颁发者的身份,并且我在 XML 中验证了签名,那么我就可以愉快地使用 SAML 响应的内容。 即用户的身份。不过,手动执行此操作仍然感觉像是错误的方法,但前提是没有明显的缺点,我就可以接受。

一些相关的SO问题和文章:

  • 如何将 SAML XML 令牌字符串转换为 SecurityToken 或 ClaimsPrincipal 实例?
  • Web.config 将 SAML 安全令牌转换为声明主体
  • 在 C# .NET 4.5 中使用 SAML 2.0
  • http://www.cloudidentity.com/blog/2013/03/25/a-refresh-of-the-identity-and-access-tool-for-vs-2012/

如何在 .net 4.5 中针对 AzureAD 实现 SAML2 身份验证?(使用令牌)

正如你所发现的 - 即使支持 SAML2 令牌,.NET 中也没有对 SAML2 协议的内置支持。

与其自己动手,我建议你查看SAML2P的可用开源和商业库,ASP.NET。在 .NET 框架中提供的内容之上构建可靠的服务提供商需要做很多工作。(我知道,因为我已经建立了一个,如果我知道我现在知道的,我想我不会再这样做了(。

如果您选择自己继续,Saml2SecurityTokenHandler包含用于从 XML 读取断言、将其转换为声明标识以及验证断言上的签名的重要工具。请注意,处理程序希望对断言进行签名 - AFAIK 没有内置支持来处理整个 SAML 响应已签名的情况(这也涵盖了嵌入式断言(。

使用 Kentor.AuthServices

此处描述的方案是直接使用 Kentor.AuthServices API,这是一个高级方案,不建议作为首选。对于Web API和现代MVC应用程序,最好使用Kentor.AuthServices.Owin包中的Owin中间件。

这里的代码使用的是Kentor.AuthServices.HttpModule包中的API。

配置

要直接使用AuthServices API,您首先必须创建一个配置,如文档中所述。可以在代码和 web.config 中执行此操作。对于此示例,我将仅引用一个Options属性,该属性是一个IOptions实例。它可以通过 Options.FromConfiguration 属性从 web.config 加载。

发送自动请求

身份验证的第一步是发送 AuthnRequest。dummyUrl只是任何非空 Uri 对象。它不会在此方案中使用,但不允许为 null。

var idp = Options.IdentityProviders.Default;
var urls = new AuthServicesUrls(fullUrlOfYourAcsService, dummyUrl, applicationUrl);
var authnRequest = idp.CreateAuthenticateRequest(dummyUrl, urls);
// Apply will call Response.End
idp.Bind(authnRequest).Apply(new HttpResponseWrapper(HttpContext.Current.Response));

即使 OP 已经设法做到这一点,也必须通过 AuthServices 完成才能正确注册挂起的请求,然后将其与返回的响应匹配。

接收响应

下一步是接收返回的 SAML2Response。此代码应位于发送 AuthnRequest 时指定的"fullUrlOfYourAcsService"位置。

var result = CommandFactory.GetCommand(CommandFactory.AcsCommandName)
  .Run(new HttpRequestWrapper(HttpContext.Current.Response), Options);
// result.Principal will now contain the received identity.