IdentityServer4-用于MVC客户端中注销的HttpPost

时间:2018-07-26 15:40:05

标签: c# identityserver4 openid-connect owin-middleware

我正在使用IdentityServer4,我的客户端之一是.NET 4.5 MVC应用程序。 一切似乎都按预期进行。但是,我有一个问题。遵循以下流程:

  1. 用户登录并重定向到客户端应用程序。
  2. 用户成功执行了不同的操作。
  3. id令牌到期(例如5分钟后)。
  4. 用户尝试POST请求(例如,注销请求)。
  5. 由于id令牌已过期并且注销操作受到[Authorize]属性的保护,由于UseOpenIdConnectAuthentication文件中的Startup.cs,它将自动转到IdentityServer4来获取新的执行任何操作之前的id令牌。
  6. 对IdentityServer4的调用已完成,并且新的id令牌已成功返回。
  7. 现在使用 GET 方法而不是 POST 方法调用注销操作,这当然不是我控制器中的操作。

如何确保收到新的ID令牌后,原始请求得以执行? (在这种情况下,是POST请求)。或者换句话说,当id令牌已过期时,如何确保可以在MVC客户端中使用HttpPost注销操作注销?

仅需说明一下,注销操作只是一个示例。可能是其他任何POST操作。

我怀疑我可能在这里丢失了一些东西,可能是由于没有使用IdentityServer4的丰富经验。

这里是我代码的清理版本,以防万一:

app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions()
{
    Authority = authenticationAuthority,
    ClientId = clientId,
    ResponseType = "code id_token",
    SignInAsAuthenticationType = "Cookies",
    Scope = "openid company.profile offline_access",

    Notifications = new OpenIdConnectAuthenticationNotifications
    {
        AuthorizationCodeReceived = async n =>
        {
            n.RedirectUri = GetRedirectUriWithCorrectScheme(n.Request.Headers);

            // use the code to get the access and refresh token
            var secret = "mysecret";
            var tokenClient = new TokenClient($"{authenticationAuthority}connect/token", clientId,
                secret);

            var tokenResponse = await tokenClient.RequestAuthorizationCodeAsync(
                n.Code, n.RedirectUri);

            if (tokenResponse.IsError)
            {
                throw new Exception(tokenResponse.Error);
            }

            // use the access token to retrieve claims from userinfo
            var userInfoClient = new UserInfoClient($"{authenticationAuthority}connect/userinfo");

            var userInfoResponse = await userInfoClient.GetAsync(tokenResponse.AccessToken);

            userInfoResponse.Claims.ToList().ForEach(claim => claims.Add(claim));

            claims.Add(new Claim("access_token", tokenResponse.AccessToken));
            claims.Add(new Claim("id_token", n.ProtocolMessage.IdToken));
            claims.Add(new Claim("refresh_token", tokenResponse.RefreshToken));

            n.AuthenticationTicket = new AuthenticationTicket(
                new ClaimsIdentity(claims.Distinct(new ClaimComparer()),
                    n.AuthenticationTicket.Identity.AuthenticationType),
                n.AuthenticationTicket.Properties);
        },

        RedirectToIdentityProvider = n =>
        {
            // if signing out, add the id_token_hint
            if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.LogoutRequest)
            {
                var idTokenHint = n.OwinContext.Authentication.User.FindFirst("id_token");

                if (idTokenHint != null)
                {
                    n.ProtocolMessage.IdTokenHint = idTokenHint.Value;
                }
            }

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

0 个答案:

没有答案