Sandeep
Sandeep

Reputation: 1210

IdentityServer4 - Redirect to MVC client after Logout

I am using IdenetityServer4 and Redirecting to MVC client after Logout is not working. Following is my MVC client controller Logout action:

public async Task Logout()
{
    await HttpContext.Authentication.SignOutAsync("Cookies");
    await HttpContext.Authentication.SignOutAsync("oidc");
}

Following is identity server 4 Host config file.

public static IEnumerable<Client> GetClients()
{
    return new List<Client>
    {
        // other clients omitted...

        // OpenID Connect implicit flow client (MVC)
        new Client
        {
            ClientId = "mvc",
            ClientName = "MVC Client",
            AllowedGrantTypes = GrantTypes.Implicit,

            // where to redirect to after login
            RedirectUris = { "http://localhost:58422/signin-oidc" },

            // where to redirect to after logout
            PostLogoutRedirectUris = { "http://localhost:58422/signout-callback-oidc" },

            AllowedScopes = new List<string>
            {
                IdentityServerConstants.StandardScopes.OpenId,
                IdentityServerConstants.StandardScopes.Profile
            }
        }
    };
} 

I want user to be redirect back to MVC client after getting Logged out from IdentityServer. Right now user has to click link show in below image to redirected back to MVC site but i think user should be automatically redirected back to MVC client.

enter image description here

Upvotes: 20

Views: 24124

Answers (3)

Lapenkov Vladimir
Lapenkov Vladimir

Reputation: 3218

No extra code is needed. You should ensure if Model.AutomaticRedirectAfterSignOut=true and signout-redirect.js exists in wwwroot/js and in LoggedOut.cshtml

@if (Model.AutomaticRedirectAfterSignOut)
    {
        <script src="~/js/signout-redirect.js"></script>
    }

makes all work (see code below)

window.addEventListener("load", function () {
    var a = document.querySelector("a.PostLogoutRedirectUri");
    if (a) {
        window.location = a.href;
    }
});

thus user is redirected to mvc from LoggedOut.cshtml

Upvotes: 2

Luke Vo
Luke Vo

Reputation: 20778

If anyone is using the Scaffolding (they use the Razor Page files), here is how to fix it according to the answer of Akhilesh:

In Areas\Identity\Pages\Account\Logout.cshtml:

First, add IIdentityServerInteractionService service:

    IIdentityServerInteractionService _interaction;

    public LogoutModel(SignInManager<IdentityUser> signInManager, ILogger<LogoutModel> logger, IIdentityServerInteractionService _interaction)
    {
        _signInManager = signInManager;
        _logger = logger;
        this._interaction = _interaction;
    }

You may need to add support for OnGet(), logic maybe different depends on your case, in my case, Get or Post does not matter:

    public async Task<IActionResult> OnGet(string returnUrl = null)
    {
        return await this.OnPost(returnUrl);
    }

Add the LogoutId logic in OnPost:

    public async Task<IActionResult> OnPost(string returnUrl = null)
    {
        await _signInManager.SignOutAsync();
        _logger.LogInformation("User logged out.");

        var logoutId = this.Request.Query["logoutId"].ToString();

        if (returnUrl != null)
        {
            return LocalRedirect(returnUrl);
        }
        else if (!string.IsNullOrEmpty(logoutId))
        {
            var logoutContext = await this._interaction.GetLogoutContextAsync(logoutId);
            returnUrl = logoutContext.PostLogoutRedirectUri;

            if (!string.IsNullOrEmpty(returnUrl))
            {
                return this.Redirect(returnUrl);
            }
            else
            {
                return Page();
            }
        }
        else
        {
            return Page();
        }
    }

Upvotes: 14

heyAkhilesh
heyAkhilesh

Reputation: 649

There is no problem in your Config.cs or in the MVC controller.

Go to your IdentityServer4 Application then inside AccountController's Logout [HttpPost] method, do the following changes:

public async Task<IActionResult> Logout(LogoutViewModel model)
{
   ...    
  //return View("LoggedOut", vm);
  return Redirect(vm.PostLogoutRedirectUri);
}

This will redirect the user back to MVC application (in your case).

There is a better way to do this: You can set these options from AccountOptions.cs as follows:

public static bool ShowLogoutPrompt = false;
public static bool AutomaticRedirectAfterSignOut = true;

Upvotes: 45

Related Questions