OWIN身份验证中间件:注销

时间:2017-09-23 14:08:19

标签: asp.net-mvc authentication owin owin-middleware

OWIN初学者在这里。请耐心等待......

我正在尝试构建一个OWIN身份验证中间件,它使用表单帖子与我的外部身份验证提供程序进行通信。我在验证位工作方面取得了一些成功。换句话说,我可以:

  1. 通过表单发布与远程提供商沟通;
  2. 处理删除提供程序返回的响应
  3. 如果一切正常,我可以发出默认身份验证提供商的信号
  4. 然后由cookie中间件拾取,最终生成身份验证cookie
  5. 到目前为止,这么好。现在,我想知道的是如何处理注销请求。目前,控制器只需从owin上下文中获取默认的身份验证管理器并调用其SingOut方法。这实际上结束了我当前的会话(通过删除cookie),但它对现有的"外部"实际上没有任何作用。会话。

    所以,这是我的问题:  1.身份验证中间件是否也负责执行注销请求?  如果是这种情况,那么有人能指出一些关于它是如何完成的文档/示例吗?我在网上找到了一些描述部分登录的链接,但是没有找到关于注销过程的任何信息......

    感谢。

    路易斯

1 个答案:

答案 0 :(得分:1)

经过一番挖掘,我设法让一切正常。我会写一些技巧,可以帮助将来遇到类似问题的人......

关于第一个问题,答案是肯定的,您可以将注销委派给中间件。如果您决定这样做,那么您的中间件处理程序应该覆盖ApplyResponseGrantAsync方法并检查是否存在当前的撤销请求。以下是一些有助于说明原则的代码:

protected override async Task ApplyResponseGrantAsync() {
    var revoke = Helper.LookupSignOut(Options.AuthenticationType, 
                                               Options.AuthenticationMode);
    var shouldEndExternalSession = revoke != null;
    if (!shouldEndExternalSession) {
       return;
    }
    //more code here...
 }

在检查是否有撤销请求后,如果您的外部身份验证提供程序能够通过重定向结束响应,那么您只需调用Response.Redirect方法(不要忘记检查重定向的存在 - 例如:如果您使用asp.net身份和MVC自动生成的代码,则注销会将您重定向到您网站的主页)。

在我的场景中,事情有点复杂,因为与我的身份验证提供程序的通信基于表单帖子(SAML2 messages with HTTP Post binding)。我开始尝试使用Response.Write将带有autopostback表单的HTML注入输出缓冲区:

protected override async Task ApplyResponseGrantAsync() {
    //previous code + setup removed
    var htmlForm = BuildAndSubmitFormWithLogoutData(url, 
                        Options.UrlInicioSessaoAutenticacaoGov);
    Response.StatusCode = 200;
    Response.ContentType = "text/html";
    await Response.WriteAsync(htmlForm);
}

不幸的是,它根本没有成功。不确定原因,但浏览器坚持将页面重定向到Logoff控制器方法定义的URL(将页面重定向到其主页或' /')。我甚至试图从ApplyResponseGrantAsync方法中删除位置HTTP标头,但它仍然最终将用户重定向到主页(而不是加载我正在编写的预定义HTML)。

我最终更改了重定向,以便我的中间件处理它。这是我在ApplyResponseGrant方法中最终得到的最终代码:

protected override async Task ApplyResponseGrantAsync() {
    //previous code + setup removed
    //setup urls for callbabk and correlation ids
    var url = ...; //internal cb url that gets handled by this middleware
    Response.Redirect(url);
}

此重定向强制我更改InvokeAsync实现,以便它现在负责:

  1. 检查新的身份验证会话
  2. 检查现有身份验证会话的结束(处理来自外部提供商的注销响应)
  3. 检查是否应生成新的表格后html消息,该消息结束由外部提供商控制的当前会话
  4. 这里有一些伪代码试图说明这一点:

    public override async Task<bool> InvokeAsync() {
        if (Options.InternalUrlForNewSession.HasValue && 
                   Options.InternalUrlForNewSession == Request.Path) {
               return await HandleLoginReply(); /login response
        }
        if (Options.InternalUrlExternalSessionEnded.HasValue && 
                   Options.InternalUrlExternalSessionEnded == Request.Path) {
               return await HandleLogoffReply();//logoff response
        }
        if (Options.InternalUrlForEndingSession.HasValue &&   
                    Options.InternalUrlForEndingSession == Request.Path) {
                return await HandleStartLogoutRequest(); //start logoff request 
        }
        return false;
    }
    

    是的,最后,我结束了额外的请求,IMO不应该被要求。再一次,我可能错过了一些东西。如果有人设法让ApplyResponseGrantAsync返回自动提交帖子(而不是重定向),请告诉我如何。

    感谢。