OpenID Connect的OWIN中间件 - 代码流(Flow type - AuthorizationCode)文档?

时间:2015-11-11 23:40:38

标签: asp.net-mvc oauth-2.0 owin openid-connect identityserver3

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

我计划使用OID代码流(使用Scope Open_ID)来验证客户端(RP)。对于OpenID连接中间件,我使用的是OWIN(Katana Project)组件。

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

我可以在https://github.com/IdentityServer/IdentityServer3.Samples/tree/master/source

找到ID Server v3的通用代码流实现的示例

我正在寻找使用OWIN中间件的类似产品?有没有人有任何指针?

2 个答案:

答案 0 :(得分:26)

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作为示例。

答案 1 :(得分:1)

Pinpoint的回答和评论回复都是现货。谢谢!

但是如果您愿意离开NuGet包而不是为Microsoft.Owin.Security.OpenIdConnect运行修改后的源代码,您可以使用form_post获取代码(code)。

当然,对于所有开源项目问题都可以说这个问题,但这对我的案例来说是一个快速的解决方案,所以我想我会分享它可以成为一个选项

我从https://github.com/aspnet/AspNetKatana下载了代码,将csproj添加到我的解决方案中,并从AuthenticateCoreAsync()中的https://github.com/aspnet/AspNetKatana/blob/dev/src/Microsoft.Owin.Security.OpenIdConnect/OpenidConnectAuthenticationHandler.cs中删除了行。

然后,您必须将其与backchannel调用结合使用,然后创建自己的新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;
    }
    ..