如何在 .net 4.5 中针对 AzureAD 实施 SAML2 身份验证? (消费代币)

How to implement SAML2 authentication in .net 4.5 against AzureAD? (Consuming Tokens)

我想允许对我的 Web 应用程序进行 SAML 身份验证,包括针对作为身份提供者的 AzureAD 以及 ADFS。 (任何人都可以给我指出一个好的教程或演练吗?)到目前为止,我已经生成了 SAML 请求,从 AzureAD 取回 SAMLP 响应,并验证其签名(包括它是 SHA256 的事实默认情况下不起作用)。

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

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

This blog 表示不使用 ConfigurationBasedIssuerNameRegistry,而是指向 [ValidatingIssuerNameRegistry][3]。好的,这似乎适合我的情况。

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

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

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

如您所知 - .NET 中没有对 SAML2 协议的内置支持,尽管支持 SAML2 令牌。

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

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

使用Kentor.AuthServices

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

此处的代码使用 Kentor.AuthServices.HttpModule 包中的 API。

配置

要直接使用 AuthServices API,您首先必须创建一个配置,如 docs 中所述。在代码和 web.config 中都可以做到。对于这个例子,我将只引用一个 Options 属性,它是一个 IOptions 实例。它可以从 web.config 通过 Options.FromConfiguration 属性.

加载

发送 AuthnRequest

身份验证的第一步是发送 AuthnRequest。 dummyUrl 只是任何非空 Uri 对象。在这种情况下不会使用它,但不允许为空。

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.