用于 OpenID Connect 的 OWIN 中间件 - 代码流(流类型 - AuthorizationCode)文档?

OWIN middleware for OpenID Connect - Code flow ( Flow type - AuthorizationCode) documentation?

在我的实现中,我使用 OpenID-Connect Server (Identity Server v3+) 来验证 Asp.net MVC 5 应用程序(使用 AngularJS 前端)

我打算使用 OID 代码流(范围 Open_ID)来验证客户端 (RP)。对于 OpenID 连接中间件,我使用的是 OWIN(Katana 项目)组件。

在实现之前,我想了解使用 OWIN 的反向通道令牌请求、刷新令牌请求过程等。但是我无法找到此类实现的任何文档(大多数可用示例使用隐式流量)。

我可以在此处找到 ID Server v3 的通用代码流实施示例 https://github.com/IdentityServer/IdentityServer3.Samples/tree/master/source

我正在寻找使用 OWIN 中间件的类似软件?有人有任何指示吗?

编辑:好消息,代码流和 response_mode=query 支持终于添加 到 Katana,作为 4.1 版本(2019 年 11 月发布)的一部分:https://github.com/aspnet/AspNetKatana/wiki/Roadmap#410-release-november-2019


OpenID Connect 中间件不支持代码流:http://katanaproject.codeplex.com/workitem/247(但已在 ASP.NET 5 版本中修复)。

实际上,官方只支持隐式流(id_token),您必须使用response_mode=form_post扩展。尝试使用授权代码流只会导致在回调期间抛出异常,因为它无法从身份验证响应中提取(丢失的)id_token

虽然不直接支持,但您也可以使用混合流程 (code + id_token (+ token)),但由您来实现令牌请求部分。您可以查看 https://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/blob/dev/samples/Nancy/Nancy.Client/Startup.cs#L82-L115 作为示例。

Pinpoint 的回答和评论回复很到位。谢谢!

但是,如果您愿意放弃 NuGet 包,而是 运行 修改 Microsoft.Owin.Security.OpenIdConnect 的源代码,您可以获得代码 (code) 流 form_post.

当然这可以适用于所有开源项目问题,但在我的案例中这是一个大问题的快速解决方案所以我想我会分享它 可以是一种选择。

我在 AuthenticateCoreAsync() 中从 https://github.com/aspnet/AspNetKatana, added the csproj to my solution and removed lines from https://github.com/aspnet/AspNetKatana/blob/dev/src/Microsoft.Owin.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs 下载了代码。

然后您必须将其与反向渠道调用结合起来,然后创建您自己的新 ClaimsIdentity() 以设置为 notification.AuthenticationTicket。

// Install-Package IdentityModel to handle the backchannel calls in a nicer fashion
AuthorizationCodeReceived = async notification =>
{
    var configuration = await notification.Options.ConfigurationManager
             .GetConfigurationAsync(notification.Request.CallCancelled);

    var tokenClient = new TokenClient(configuration.TokenEndpoint,
             notification.Options.ClientId, notification.Options.ClientSecret,
                  AuthenticationStyle.PostValues);
    var tokenResponse = await tokenClient.RequestAuthorizationCodeAsync(
        notification.ProtocolMessage.Code,
        "http://localhost:53004/signin-oidc",
        cancellationToken: notification.Request.CallCancelled);

    if (tokenResponse.IsError 
            || string.IsNullOrWhiteSpace(tokenResponse.AccessToken)
            || string.IsNullOrWhiteSpace(tokenResponse.RefreshToken))
    {
        notification.HandleResponse();
        notification.Response.Write("Error retrieving tokens.");
        return;
    }

    var userInfoClient = new UserInfoClient(configuration.UserInfoEndpoint);
    var userInfoResponse = await userInfoClient.GetAsync(tokenResponse.AccessToken);

    if (userInfoResponse.IsError)
    {
        notification.HandleResponse();
        notification.Response.Write("Error retrieving user info.");
        return;
    }
    ..