【问题标题】:OWIN authentication middleware: logging offOWIN 认证中间件:注销
【发布时间】:2017-09-23 14:08:18
【问题描述】:

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

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

  1. 通过表单发送与远程提供商沟通;
  2. 处理移除提供程序返回的响应
  3. 如果一切正常,我可以向默认身份验证提供程序发出信号
  4. 这反过来被 cookie 中间件拾取,最终生成身份验证 cookie

到目前为止,一切都很好。现在,我想知道的是如何处理注销请求。目前,控制器将简单地从 owin 上下文中获取默认身份验证管理器并调用其 SingOut 方法。这实际上结束了我当前的会话(通过删除 cookie),但它确实对现有的“外部”会话没有任何作用。

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

谢谢。

路易斯

【问题讨论】:

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


    【解决方案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 将带有自动回发表单的 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. 检查它是否应该生成一个新的表单 post html 消息以结束由外部提供程序控制的当前会话

    这里有一些伪代码试图说明这一点:

    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 返回自动提交帖子(而不是重定向),请告诉我如何。

    谢谢。

    【讨论】:

    • 您可以通过覆盖AuthenticationMiddleware.Invoke( ) 来停止重定向,例如“await base.Invoke(context); If (context.Response.StatusCode==302) { context.Response .StatusCode=200; context.Response.Headers.Remove("location"); ...}"
    猜你喜欢
    • 1970-01-01
    • 2011-09-22
    • 2014-04-29
    • 2021-02-07
    • 2017-11-07
    • 2014-08-24
    • 2015-11-30
    • 2012-09-09
    • 1970-01-01
    相关资源
    最近更新 更多