Dumi
Dumi

Reputation: 1434

Keycloak Logout does not work with ASP.NET MVC

I have integrated Keycloak to my ASP.NET MVC project running on .NET 4.7.

This is my startup.cs:

public void Configuration(IAppBuilder app)
{
    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

    app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
        AuthenticationType = CookieAuthenticationDefaults.AuthenticationType
    });
    app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

    app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
    {
        ClientId = keycloakClient,
        ClientSecret = keycloakClientSecret,
        Authority = String.Format("{0}/realms/{1}", keycloakBaseUrl, keycloakRealm),
        RedirectUri = homeUrl,//+ "signin-oidc",
        ResponseType = OpenIdConnectResponseType.IdTokenToken,
        Scope = OpenIdConnectScope.OpenIdProfile,
        SignInAsAuthenticationType = CookieAuthenticationDefaults.AuthenticationType,
        PostLogoutRedirectUri = homeUrl,
        UseTokenLifetime = true,

        TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = false,
            NameClaimType = ClaimTypes.Name, 
            RoleClaimType = ClaimTypes.Role
        },
        Notifications = new OpenIdConnectAuthenticationNotifications
        {
            RedirectToIdentityProvider = n =>
            {
                if (n.ProtocolMessage.RequestType == OpenIdConnectRequestType.Logout)
                {
                    var id_token_claim = n.OwinContext.Authentication.User.Claims.FirstOrDefault(x => x.Type == "id_token");
                    if (id_token_claim != null)
                    {
                        n.ProtocolMessage.IdTokenHint = id_token_claim.Value;
                    }
                }
                return Task.FromResult(0);
            },
            SecurityTokenValidated = (context) =>
            {
                var identity = context.AuthenticationTicket.Identity;

                var idToken = context.ProtocolMessage.IdToken;

                identity.AddClaim(new Claim("id_token", idToken));

                var handler = new JwtSecurityTokenHandler();
                var jsonToken = handler.ReadToken(idToken) as JwtSecurityToken;

                var subClaim = jsonToken?.Claims.FirstOrDefault(c => c.Type == "sub");
                if (subClaim != null)
                {
                    var subValue = subClaim.Value;

                    identity.AddClaim(new Claim("keycloak_id", subValue));
                }

                context.AuthenticationTicket.Identity.AddClaim(new Claim("access_token", context.ProtocolMessage.AccessToken));
                context.AuthenticationTicket.Identity.AddClaim(new Claim("id_token", context.ProtocolMessage.IdToken));

                return Task.CompletedTask;
            },
            AuthenticationFailed = (context) =>
            {
                return Task.CompletedTask;
            }
        }
    });
}

And AccountController.cs:

Login button will call the Login method shown here. Since it has [Authorize] attribute, it redirects to the keycloak login page.

 [Authorize]
 public void KeycloakLogin()
 {
 }

When logout button is clicked, it will call the below method.

[Authorize]
public ActionResult KeycloakLogout()
{
    var id_token = GetIDToken();
    
    string keycloakLogoutUrl = String.Format("{0}/realms/{1}/protocol/openid-connect/logout?id_token_hint={2}&post_logout_redirect_uri={3}", keycloakBaseUrl, keycloakRealm, id_token, ConfigurationManager.AppSettings["SiteURL"]);
    return Redirect(keycloakLogoutUrl);
}

After that it is redirecting to the home page. But still, the Keycloak session is not ended. Request.IsAuthenticated is true. How to resolve this?

Upvotes: 0

Views: 140

Answers (0)

Related Questions