|
I have the following setup: Blazor WebAssembly frontend => Api + openiddict backend + a separate login provider using windows ADFS. In the backend I have configured .AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, to add the external ADFS provider. Now when the user hit's the logout button. (using the default authentication/logout link) The user get's logged off by the OpenIddict session. But the problem is, that the endpoint for the ADFS endpoint (adfs/oauth2/logout) is never called and the user is still logged in there. What's the recommend way to achieve this ? I tried to override the LogoutModel, but that one is never hit when logging out, so I cannot use that one. Any suggestions? |
Replies: 1 comment 1 reply
|
Hi, The logout of a Blazor WASM client doesn't go through the You can replace that controller and sign out from ADFS as part of the flow. When using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.Mvc;
using OpenIddict.Server.AspNetCore;
using Volo.Abp.DependencyInjection;
using Volo.Abp.OpenIddict.Controllers;
namespace MyCompanyName.MyProjectName;
[Route("connect/endsession")]
[ApiExplorerSettings(IgnoreApi = true)]
[ExposeServices(typeof(LogoutController))]
[Dependency(ReplaceServices = true)]
public class MyLogoutController : LogoutController
{
[HttpGet]
public override async Task<IActionResult> GetAsync()
{
var result = await HttpContext.AuthenticateAsync(SignInManager.AuthenticationScheme);
var loginProvider = result.Succeeded
? result.Principal?.FindFirst(ClaimTypes.AuthenticationMethod)?.Value
: null;
await SignInManager.SignOutAsync();
if (loginProvider == OpenIdConnectDefaults.AuthenticationScheme)
{
// Sign out from the external identity provider first, then come back
// to this endpoint to complete the OpenIddict end session flow.
return SignOut(
new AuthenticationProperties
{
RedirectUri = Request.GetEncodedPathAndQuery()
},
OpenIdConnectDefaults.AuthenticationScheme);
}
return SignOut(authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme);
}
}The flow becomes: Two things to be aware of:
options.Events.OnRedirectToIdentityProviderForSignOut = context =>
{
context.ProtocolMessage.IdTokenHint = "<the ADFS id_token you saved at login>";
return Task.CompletedTask;
};Note it must be the ID token issued by ADFS, not the one your own auth server issued to the Blazor client. Don't persist it as a user claim. Thanks |
Hi,
The logout of a Blazor WASM client doesn't go through the
LogoutModelpage. It's an RP-initiated logout: the client redirects to OpenIddict's end session endpoint (connect/endsession), which is handled by theLogoutControllerof theVolo.Abp.OpenIddict.AspNetCoremodule. That controller only clears the local Identity cookies (application, temporary external and 2FA) and completes the OpenIddict sign-out, it never triggers a sign-out on your externalOpenIdConnectscheme. That's why ADFS keeps its session.You can replace that controller and sign out from ADFS as part of the flow. When
SignInManager.ExternalLoginSignInAsyncsigns the user in, the authentication cookie contains aClaimT…