找不到方法:进行Http调用时,System.Threading.Tasks.Task UserInfoResponse

时间:2019-02-19 13:38:03

标签: c# webforms httpclient identityserver4

我正在尝试在旧的WebForm应用程序上实现“单一登录”。身份验证部分成功,并且我收到访问令牌。当我尝试再次使用访问令牌联系IdentityServer并获得有关已登录用户的进一步声明时,我遇到了问题。我启动时的代码如下:

app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
    Authority = "http://localhost:50001",
    RedirectUri = "http://localhost:65438/signin-oidc",
    PostLogoutRedirectUri = "http://localhost:65438/signout-callback-oidc",
    RequireHttpsMetadata = false,
    ClientId = "webforms",
    AuthenticationType = "oidc",
    SignInAsAuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
    ResponseType = "id_token token",
    Scope = "openid profile email",
    UseTokenLifetime = false,
    Notifications = new OpenIdConnectAuthenticationNotifications
    {
        SecurityTokenValidated = async n =>
        {
            var claimsToExclude = new[]
            {
                "aud", "iss", "nbf", "exp", "nonce", "iat", "at_hash"
            };

            var claimsToKeep = n.AuthenticationTicket.Identity.Claims.Where(x => !claimsToExclude.Contains(x.Type)).ToList();

            claimsToKeep.Add(new Claim("id_token", n.ProtocolMessage.IdToken));

            if (n.ProtocolMessage.AccessToken != null)
            {
                claimsToKeep.Add(new Claim("access_token", n.ProtocolMessage.AccessToken));

                var client = new HttpClient();
                var disco = await client.GetDiscoveryDocumentAsync("http://localhost:50001");
                var userInfoResponse = await client.GetUserInfoAsync(new UserInfoRequest
                {
                    Address = disco.UserInfoEndpoint,
                    Token = n.ProtocolMessage.AccessToken
                });

                var userInfoClaims = userInfoResponse.Claims
                    .Where(x => x.Type != "sub"); // filter sub since we're already getting it from id_token

                claimsToKeep.AddRange(userInfoClaims);
            }

            var ci = new ClaimsIdentity(n.AuthenticationTicket.Identity.AuthenticationType, "name", "role");
            ci.AddClaims(claimsToKeep);

            n.AuthenticationTicket = new Microsoft.Owin.Security.AuthenticationTicket(ci, n.AuthenticationTicket.Properties);
        },
        RedirectToIdentityProvider = n =>
        {
            if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.Logout)
            {
                n.ProtocolMessage.IdTokenHint = n.OwinContext.Authentication.User.FindFirst("id_token")?.Value;
            }

            return Task.FromResult(0);
        }
    }
});

发生问题的具体部分是:

if (n.ProtocolMessage.AccessToken != null)
{
    claimsToKeep.Add(new Claim("access_token", n.ProtocolMessage.AccessToken));

    var client = new HttpClient();
    var disco = await client.GetDiscoveryDocumentAsync("http://localhost:50001");
    var userInfoResponse = await client.GetUserInfoAsync(new UserInfoRequest
    {
        Address = disco.UserInfoEndpoint,
        Token = n.ProtocolMessage.AccessToken
    });

    var userInfoClaims = userInfoResponse.Claims
        .Where(x => x.Type != "sub"); // filter sub since we're already getting it from id_token

    claimsToKeep.AddRange(userInfoClaims);
}

由于这是在中间件中,因此调试起来不是很容易,但是发生的异常是这样的:

Method not found: 'System.Threading.Tasks.Task`1<IdentityModel.Client.UserInfoResponse> IdentityModel.Client.HttpClientUserInfoExtensions.GetUserInfoAsync(System.Net.Http.HttpMessageInvoker, IdentityModel.Client.UserInfoRequest, System.Threading.CancellationToken)'.

有什么建议吗?预先感谢!

0 个答案:

没有答案