我想允许我的Web应用程序进行SAML身份验证,包括针对AzureAD作为身份提供程序以及ADFS。(任何人都可以向我指出一个好的教程或演练吗?)到目前为止,我已经生成了SAML请求,从AzureAD取回SAMLP响应,并验证了其签名(包括SHA256无法正常工作的事实)默认情况下)。
现在,我想从中提取信息以验证发行者,并获取用户的电子邮件以进行识别。通过XML手动执行此操作是否可以,还是应该使用Saml2SecurityTokenHandler之类的类?它们看起来像他们应该做的那样,但是我发现很难从安全的角度理解所有必需的配置以及是否有必要使用此类。
我的应用程序是多租户,因此我需要代码而不是配置来处理Saml,因为不同的租户将使用不同的身份验证选项。
该博客说不使用ConfigurationBasedIssuerNameRegistry
,而是指向[ValidatingIssuerNameRegistry][3]
。好的,这似乎适合我的情况。
在此问题中,有一些代码以编程方式配置受信任的颁发者,因此我可以进行调整以使用ValidatingIssuerNameRegistry,然后大概可以使用tokenHandlersAssertion
从SAMLP响应中读取,然后提取包括名称(电子邮件)的声明。但是,在哪里可以从AzureAD元数据传递指纹和名称呢?而使用这些类而不是自己解析响应到底有什么价值呢?确实感觉要为此使用一个库是正确的事情,但是WIF的复杂性以及缺乏有关此操作的演练文章使人们觉得除了身份领域的那些人以外,这似乎是不合适的。
我的猜测是,如果我已经有本地存储的证书来验证SAML响应的颁发者的身份,并且在XML中验证了签名,那么我可以很高兴地使用SAML响应的内容。即用户的身份。仍然感觉像是手动执行此操作的错误方法,但是如果没有明显的缺点,我可以接受。
一些相关的SO问题和文章:
如您所知-即使支持SAML2令牌,.NET也没有内置支持SAML2协议。
建议您不要自己研究,而应该研究适用于ASP.NET的SAML2P的可用开源和商业库。除了.NET框架中提供的功能之外,还有很多工作来构建可靠的服务提供者。(我知道,因为我已经建立了一个,如果我知道我现在知道的东西,我认为我不会再做一次)。
如果您选择自己动手,则Saml2SecurityTokenHandler
其中包含用于从XML读取断言,将其转换为声明标识并验证断言签名的重要工具。请注意,处理程序希望断言被签名-AFAIK没有内置支持来处理整个SAML响应已签名(也涵盖嵌入式断言)的情况。
此处描述的方案直接使用Kentor.AuthServices API,这是一种高级方案,不建议将其作为首选方案。对于Web API和现代MVC应用程序,最好使用Kentor.AuthServices.Owin包中的Owin中间件。
此处的代码使用的是Kentor.AuthServices.HttpModule包中的API。
要直接使用AuthServices API,您首先必须创建一个配置,如docs中所述。既可以在代码中也可以在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.
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句