I am implementing openidconnect authentication using keycloak server in my asp.net core application. The login works ok, but I'm not able to implement logout. The behavior is that it takes me to the home page of my web app; instead it should take me to the keycloak login page. Below is my code:
Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(options =>
{
// Store the session to cookies
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
// OpenId authentication
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie(cookie =>
{
cookie.Cookie.Name = "keycloak.cookie";
cookie.Cookie.MaxAge = TimeSpan.FromMinutes(60);
cookie.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
cookie.SlidingExpiration = true;
})
.AddOpenIdConnect(options =>
{
options.Authority = Configuration.GetSection("Keycloak")["Authority"];
//Keycloak client ID
options.ClientId = Configuration.GetSection("Keycloak")["ClientId"];
//Keycloak client secret
options.ClientSecret = Configuration.GetSection("Keycloak")["ClientSecret"];
// For testing we disable https (should be true for production)
options.RequireHttpsMetadata = false;
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
// OpenID flow to use
options.ResponseType = OpenIdConnectResponseType.CodeIdToken;
options.Events.OnSignedOutCallbackRedirect += context =>
{
context.Response.Redirect(context.Options.SignedOutRedirectUri);
context.HandleResponse();
return Task.CompletedTask;
};
});
}
Index.shtml:
<a class="nav-link text-light" asp-page-handler="Logout" asp-page="/Pages/Index">Sign out</a>
Index.cshtml.cs:
public IActionResult Logout()
{
return new SignOutResult(
new[] {
OpenIdConnectDefaults.AuthenticationScheme,
CookieAuthenticationDefaults.AuthenticationScheme
});
}
You are not supposed to return anything from the Logout method, because SignOutAsync genereates its own response.
So, this is how I do logouts in my applications:
/// <summary>
/// Do the logout
/// </summary>
/// <returns></returns>
[HttpPost]
[ValidateAntiForgeryToken]
public async Task Logout()
{
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
await HttpContext.SignOutAsync(OpenIdConnectDefaults.AuthenticationScheme);
//Important, this method should never return anything.
}