在CookieAuthenticationProvider()

时间:2017-10-19 17:10:40

标签: asp.net-mvc authentication cookies owin ws-federation

我正在使用由WsFederationAuthentication和CookieAuthentication OWIN组件保护的MVC5应用程序。作为登录过程的一部分,我在设置OnResponseSignIn的{​​{1}}代理期间向SAML提供程序返回的ClaimsIdentity(在本例中为ADFS)中注入了一些其他声明。在启动期间。这允许我在OwinContext用于生成故障单之前操纵ClaimsIdentity。在实践中,这非常适合我过去需要做的事情(主要是根据与传入索赔提供的数据相匹配的数据库中添加的自定义声明)。

但是,根据执行CookieAuthenticationProvider时出现的情况,我现在需要能够以这样一种方式拒绝登录,即我可以向用户显示错误,说明它为什么不是他们可能会登录。事实证明这比我想象的要复杂得多。

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

  1. 在CookieAuthenticationProvider.OnResponseSignIn中抛出异常
    这是因为永远不会设置身份验证cookie,我的全局错误处理程序会捕获异常并将其显示给用户。但是,在抛出异常之前,我无法确定有效拒绝身份的方法。因此,我的全局错误处理程序认为HttpContext已经过身份验证,并使用在未对用户进行身份验证时不应呈现的元素呈现错误视图。在OnResponseSignIn中取消OwinContext.Identity没有效果,因为我所做的只是清除OnResponseSignInContext中的一个值,该值对整个管道没有影响。据我所知,我不能将实际的ClaimsIdentity标记为未经过身份验证,因为当您在ClaimsIdentity ctor中设置身份验证类型时,IsAuthenticated设置为true,并且在此之后无法修改。

  2. 添加"错误"在CookieAuthenticationOptions中声称面包屑然后在OnResponseSignIn中查找并在那里抛出异常。
    这种方法的好处是能够清除登录(CookieAuthenticationProvider.OnResponseSignIn提供的好处)。所以,现在我的错误视图正确呈现给未经身份验证的用户。但是,这里的问题是我无法找到一种方法来阻止在CookieAuthenticationProvider.OnValidateIdentity之后创建的身份验证cookie被发送到客户端并在浏览器中设置。我在这些代理中提供的工具允许我追加和删除OnValidateIdentityContext.RejectIdentity()中的cookie,但不知何故,这个cookie不是我能做到的。它似乎实际上被添加到管道中的后面的响应流中,我无法对其进行更改。因此,如果我让OnResponseSignIn完成,然后在执行OwinContext期间查找Cookie,我就不会在那里看到它。真的不确定为什么会这样 - 看CookieAuthenticationHandler的来源,看起来我应该看到它,因为它是在执行这两个OnResponseSignIn代表之间添加的。我也无法阻止cookie首先生成,因为如果票证无法序列化,CookieAuthenticationHandler将抛出异常。

  3. 所以,我要么不能设置cookie,要么得到验证错误视图,或者获得未经身份验证的错误视图,但是有一个cookie集可以有效地防止用户再次尝试登录。

    最终,我已经在框架的泥泞中滚动,此时我觉得我必须正确地解决问题。我正在寻找的是这个问题的答案:

    如何拒绝其他有效的WsFederation身份验证回发并向用户显示错误,解释发生的事情而不向客户端发送AuthenticationTicket?

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

1 个答案:

答案 0 :(得分:2)

您可能在启动代码中使用了类似的内容:

app.UseWsFederationAuthentication(new WsFederationAuthenticationOptions())

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