Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/hadoop/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Identityserver4 具有标识4和OIDClient的授权代码流_Identityserver4_Identitymodel_Oidc Client - Fatal编程技术网

Identityserver4 具有标识4和OIDClient的授权代码流

Identityserver4 具有标识4和OIDClient的授权代码流,identityserver4,identitymodel,oidc-client,Identityserver4,Identitymodel,Oidc Client,对于Winforms桌面应用程序,我将使用PKCE的授权代码流。作为身份提供者,我使用和作为客户端库。 下一步,我必须决定使用哪个浏览器进行用户登录: For SystemBrowser讲述了流程的简单/清晰实现。 对于Extended WebBrowser,有些用户可能没有系统浏览器。但是WebBrowser是一个旧的IE版本吗?它是否允许用于安全身份验证 尽管如此,我还是尝试了“ExtendedWebBrowser”示例,并将其与自己的IS4服务器集成到我的原型环境中。因此,我需要一

对于Winforms桌面应用程序,我将使用PKCE的授权代码流。作为身份提供者,我使用和作为客户端库。 下一步,我必须决定使用哪个浏览器进行用户登录:

For SystemBrowser讲述了流程的简单/清晰实现。 对于Extended WebBrowser,有些用户可能没有系统浏览器。但是WebBrowser是一个旧的IE版本吗?它是否允许用于安全身份验证

尽管如此,我还是尝试了“ExtendedWebBrowser”示例,并将其与自己的IS4服务器集成到我的原型环境中。因此,我需要一些代码流和重定向的清晰性。 我已经用纯.Net类实现了这个授权代码流,但是使用OicdClient让我有点困惑(一开始就像一个黑盒子)

我的问题是重定向如何与这些库一起工作,谁负责重定向,谁负责接收带有代码的重定向(以交换访问令牌)

代码流包含以下步骤(没有clientID、PKCE等详细信息):

  • 向IS4发送代码请求
  • 带有登录页面的IS4响应(显示在浏览器中)
  • 成功登录后,IS4用代码发送到重定向URL
  • HttpListener通过代码和
  • 向IS4发送一个请求,其中包含接收访问令牌的代码
  • 使用OIDClient并使用

    这里有很多魔术给我。只有对LoginAsync()的调用才能使其工作

    重要的一点似乎是IBrowser界面选项的浏览器属性及其此方法的实现:

        public async Task<BrowserResult> InvokeAsync(BrowserOptions options, CancellationToken cancellationToken)
        {
                using (var listener = new LoopbackHttpListener(Port, _path))
                {
                    OpenBrowser(options.StartUrl);
                    try
                    {
                        var result = await listener.WaitForCallbackAsync();
                        if (String.IsNullOrWhiteSpace(result))
                        {
                            return new BrowserResult { ResultType = BrowserResultType.UnknownError, Error = "Empty response." };
                        }
                        return new BrowserResult { Response = result, ResultType = BrowserResultType.Success };
                    }
                    catch (TaskCanceledException ex)
                    { ....}
                }
            }
    

    当前的最佳实践是使用用户的默认web浏览器,而不是嵌入浏览器组件。至于如何实现这一点——由于无法使用这种方法截获浏览器导航事件,因此需要实现一个HTTP侦听器,该侦听器可以接受来自
    identityserver4
    实现的POST请求

    读一读:

    本RFC:

        public async Task<BrowserResult> InvokeAsync(BrowserOptions options, CancellationToken cancellationToken)
        {
                using (var listener = new LoopbackHttpListener(Port, _path))
                {
                    OpenBrowser(options.StartUrl);
                    try
                    {
                        var result = await listener.WaitForCallbackAsync();
                        if (String.IsNullOrWhiteSpace(result))
                        {
                            return new BrowserResult { ResultType = BrowserResultType.UnknownError, Error = "Empty response." };
                        }
                        return new BrowserResult { Response = result, ResultType = BrowserResultType.Success };
                    }
                    catch (TaskCanceledException ex)
                    { ....}
                }
            }
    
    public async Task<BrowserResult> InvokeAsync(BrowserOptions options, CancellationToken cancellationToken = default(CancellationToken))
            {
                using (var form = _formFactory.Invoke())
                using (var browser = new ExtendedWebBrowser()
                {
                    Dock = DockStyle.Fill
                })
                {
                    var signal = new SemaphoreSlim(0, 1);
    
                    var result = new BrowserResult
                    {
                        ResultType = BrowserResultType.UserCancel
                    };
    
                    form.FormClosed += (o, e) =>
                    {
                        signal.Release();
                    };
    
                    browser.NavigateError += (o, e) =>
                    {
                        e.Cancel = true;
    
                        if (e.Url.StartsWith(options.EndUrl))
                        {
                            result.ResultType = BrowserResultType.Success;
                            result.Response = e.Url;
                        }
                        else
                        {
                            result.ResultType = BrowserResultType.HttpError;
                            result.Error = e.StatusCode.ToString();
                        }
    
                        signal.Release();
                    };
    
                    browser.BeforeNavigate2 += (o, e) =>
                    {
                        var b = e.Url.StartsWith(options.EndUrl);
                        if (b)
                        {
                            e.Cancel = true;
                            result.ResultType = BrowserResultType.Success;
                            
                            result.Response = e.Url;
                            
                            signal.Release();
                        }
                    };
    
                    form.Controls.Add(browser);
                    browser.Show();
    
                    System.Threading.Timer timer = null;
    
                    form.Show();
                    browser.Navigate(options.StartUrl);
    
                    await signal.WaitAsync();
                    if (timer != null) timer.Change(Timeout.Infinite, Timeout.Infinite);
    
                    form.Hide();
                    browser.Hide();
    
                    return result;
                }
            }
    
    result.ResultType = BrowserResultType.Success;
    result.Response = e.Url;