我已经搜索过(探测过,甚至是)一个答案,但到目前为止还没有找到任何有用的东西。我对ADFS,STS和WIF都很陌生,所以请原谅任何明显的无知或不当使用术语。 ;)
我目前正在通过ADFS将自定义MVC3应用程序与外部IdP集成。 ADFS到IdP设置已完成并正常工作。
站点的某些部分可供匿名用户访问 - 在web.config身份验证模式中已设置为none。通过自定义System.Web.Mvc.AuthorizeAttribute修饰其控制器/操作方法来保护其他部分。
已经对使用WsFederationAuthenticationModule的web.config进行了所有常规修改,它的工作率为95%;用户可以浏览到站点的非访问部分。当他们尝试点击受保护的部分时,authorize属性会检查他们是否在与HttpContext.Current.User关联的IClaimsPrincipals中的IdP中有一些自定义信息,然后将ActionResult设置为401(如果没有); WsFederationAuthenticationModule启动并将它们重定向到IdP的登录页面。当他们输入他们的详细信息时,他们会成功地使用一些FedAuth cookie重定向,然后授权通过。
当问题进入IdP的登录页面时,问题就开始了。这个特定的IdP有一个链接,可以直接返回我们的站点(原始请求所在的同一页面),这个SAML响应嵌入到某处(这是根据他们的文档)
urn:oasis:names:tc:SAML:2.0:status:AuthnFailed
此时,它们现在是“未经授权”,并且所有用户将看到(至少在开发中)是401页面。你必须杀死会话或以其他方式摆脱那个cookie才能重新开始。
我需要做的是拦截来自IdP的重定向请求,并基本上检查该特定的SAML状态,因为用户应该被重定向到其中一个未授权区域,就像没有发生任何事情一样。我在global.asax中尝试过类似的东西:
protected void Application_Start()
{
// mvc stuff here....
// add handler to intercept handling creation of security tokens by WsFederationAuthnticationModule
FederatedAuthentication.ServiceConfigurationCreated += OnServiceConfigurationCreated;
}
void OnServiceConfigurationCreated(object sender, ServiceConfigurationCreatedEventArgs e)
{
FederatedAuthentication
.WSFederationAuthenticationModule
.SessionSecurityTokenCreated += WSFederationAuthenticationModule_SecuityTokenCreated;
}
public void WSFederationAuthenticationModule_SecuityTokenCreated (Object sender, SessionSecurityTokenCreatedEventArgs args)
{
var token = args.SessionToken;
// do something with the session token here e.g. check for SAML status
}
..但我看不出有关该标记的任何有用信息;没有任何迹象表明具体的反应状态。事实上,所有都有一个FedAuth cookie 但是没有来自Idp的自定义信息是一个死的用户已经在那里,但不知何故无法进行身份验证,但原则上我希望能够看到那个状态。我可能还必须处理IdP的超时......
也许我这样做是错的,或者只是普通老不明白,但可以某种方式让我了解如何确定这些反应状态?
呼。谢谢! :d
答案 0 :(得分:2)
好的,所以我要回答我自己的问题。
目前我是否可以从我的IdP获得该自定义状态的答案是否定的。 :(
但这只是因为ADFS没有设置为捕获它并传递它。显然,您需要做一些自定义编码,以便从ADFS和IdP之间打开的后台通道中捕获信息....远远超出当前的工作范围。
暂时解决这个问题:
不太好但可以接受。顺便说一下,此YMC帖子中的所有功劳都归SO所示,以便您检查SAML令牌:
void WSFederationAuthenticationModule_SecurityTokenReceived(object sender, SecurityTokenReceivedEventArgs e)
{
var message = SignInResponseMessage.CreateFromFormPost(Request) as SignInResponseMessage;
var rstr = new WSFederationSerializer()
.CreateResponse(message,
new WSTrustSerializationContext(
SecurityTokenHandlerCollectionManager.CreateDefaultSecurityTokenHandlerCollectionManager()));
}
四氯乙烯!