在CookieAuthenticationProvider()中拒绝成功的ws-federation登录

问题描述:

我正在使用受WsFederationAuthentication和CookieAuthentication OWIN组件保护的MVC5应用程序。作为登录过程的一部分,我在启动过程中设置CookieAuthenticationOptions时提供的OnResponseSignIn代理OnResponseSignIn代理期间向SAML提供商返回的ClaimsIdentity(本例中为ADFS)注入了一些额外声明。这允许我在OwinContext中用于生成票证之前操纵ClaimsIdentity。在实践中,这对我过去需要做的事情非常有用(主要是根据数据库中找到的值与来自传入声明的数据相匹配而添加自定义声明)。在CookieAuthenticationProvider()中拒绝成功的ws-federation登录

但是,根据执行OnResponseSignIn时出现的情况,我现在需要能够拒绝登录,以便我可以向用户显示一条错误消息,指出为什么他们无法登录。这被证明比我想象的要复杂得多。

这是我尝试了两种主要的方法:

  1. 扔在CookieAuthenticationProvider.OnResponseSignIn异常:
    这工作,因为身份验证Cookie从来没有和我的全局错误处理程序捕获例外并将其显示给用户。但是,我无法确定在抛出异常之前有效拒绝身份的方法。所以,我的全局错误处理程序认为HttpContext已经过身份验证,并且如果用户未通过身份验证,则会显示错误视图,并显示不应呈现的元素。忽略OnResponseSignIn中的OwinContext.Identity并不会产生任何效果,因为我所做的只是清除OnResponseSignInContext中的一个值,该值对整个管道没有影响。据我所知,我不能将实际的ClaimsIdentity本身标记为未验证,因为当您在ClaimsIdentity ctor中设置验证类型并且之后无法修改时,IsAuthenticated设置为true。

  2. CookieAuthenticationProvider.OnResponseSignIn中添加一个“错误”声明作为面包屑,然后在CookieAuthenticationProvider.OnValidateIdentity中查找并在该处抛出异常。
    此方法的优点是能够清除登录名(由OnValidateIdentityContext.RejectIdentity()提供的好处)。所以,现在我的错误视图呈现正确的未经身份验证的用户。但是,这里的问题是,我无法想出一种方法来防止在OnResponseSignIn之后创建的身份验证Cookie发送到客户端并在浏览器中设置。我在这些代表中都有的工具允许我从OwinContext附加和删除cookie,但不知怎的,这个cookie不是我可以做到的。它看起来实际上被添加到稍后在管道中的响应流,我无法改变它。所以,如果我让OnResponseSignIn完成,然后在执行OnResponseSignedIn期间查找cookie,我在那里看不到它。真的不知道这是为什么 - 看着CookieAuthenticationHandler的来源,看起来我应该看到它,因为它是在执行这两个代表之间添加的。如果无法序列​​化票证,CookieAuthenticationHandler将引发异常,我也无法阻止首先生成Cookie。

所以,我要么可以得到没有设置Cookie和AS-如果验证的错误观点或得到一个未经验证的错误观点,但有一个cookie集,有效地防止用户尝试再次登录。

最终,我在这个框架的泥泞中滚动,在这一点上,我觉得我必须错误地接近这个问题。我正在寻找的是这个问题的答案:

我该如何拒绝其他有效的WsFederation认证回发,并向用户显示一个错误,解释发生了什么事情,而不向客户端发送AuthenticationTicket?

我猜这个过程中必须有另一个点(可能不在CookieAuthenticationProvider),这可以在管道决定认证成功之前完成。

+0

对于什么是值得的,我的(希望)临时解决方法是对'OnResponseSignIn'期间添加的声明使用测试来确定用户是否实际登录(而不是'Request.IsAuthenticated')。丑,但它的作品。 –

也许你使用这样的事情在你的启动代码:

app.UseWsFederationAuthentication(new WsFederationAuthenticationOptions()) 

WsFederationAuthenticationOptions提供挂接到wsfed认证(如CookieAuthenticationProvider的cookie身份验证)的可能性。您可以将Notifications属性设置为WsFederationAuthenticationNotifications的新实例。我建议使用SecurityTokenValidated属性并将其设置为您的实现,即匹配所需的Func<>定义的新方法。这是令牌通过验证并生成了ClaimsIdentity之后的点。然后,您可以执行额外的检查,并将方法参数SecurityTokenValidatedNotificationAuthenticationTicket设置为空并修改HttpResponse。不应该触发CookieAuthenticationHandler。

+0

啊!这看起来很有希望!我无法弄清楚如何扩展WsFed堆栈。我认为有一种方法,但我很难找到好的示例或文档。这非常有帮助。当我有时间循环和实施这个时,我会试一试,并加入我的经验。同时,我会接受答案。 –