I will try to explain my problem as simply as possible. I can't get back to the original URL, which can be recognized thanks to its ReturnUrl.
Here's what I have when I launch my application :
https://localhost:XXXX/Identity/Account/Login?ReturnUrl=%2F%3FGB%3DMjI2fC0x
So far, so good.
Then once I log in with my account, I get to the index page.
https://localhost:XXXX/?GB=MjI2fC0x
Once again, everything is fine.
But WHEN I log out, I'm coming to this one:
https://localhost:XXXX/Identity/Account/Logout
How can I make the URL to be this ?
https://localhost:XXXX/Identity/Account/Logout?ReturnUrl=%2F%3FGB%3DMjI2fC0x
or this :
https://localhost:XXXX/Identity/Account/Login?ReturnUrl=%2F%3FGB%3DMjI2fC0x
Logout.cshtml.cs
[AllowAnonymous]
public class LogoutModel : PageModel
{
private readonly SignInManager < ApplicationUser > _signInManager;
private readonly ILogger < LogoutModel > _logger;
public LogoutModel(SignInManager < ApplicationUser > signInManager, ILogger < LogoutModel > logger)
{
_signInManager = signInManager;
_logger = logger;
}
public string ReturnUrl { get; set; }
public void OnGet()
{
}
public async Task < IActionResult > OnPost(string returnUrl)
{
ReturnUrl = returnUrl;
await _signInManager.SignOutAsync();
_logger.LogInformation("User logged out.");
if (returnUrl!= null) {
return LocalRedirect(returnUrl);
}
else {
return RedirectToPage();
}
}
}
Login.cshtml.cs
[AllowAnonymous]
public class LoginModel : PageModel
{
private readonly UserManager < ApplicationUser > _userManager;
private readonly SignInManager < ApplicationUser > _signInManager;
private readonly ILogger < LoginModel > _logger;
public LoginModel(SignInManager < ApplicationUser > signInManager,
ILogger < LoginModel > logger,
UserManager < ApplicationUser > userManager)
{
_userManager = userManager;
_signInManager = signInManager;
_logger = logger;
}
[BindProperty]
public InputModel Input { get; set; }
public IList < AuthenticationScheme > ExternalLogins { get; set; }
public string ReturnUrl { get; set; }
[TempData]
public string ErrorMessage { get; set; }
public class InputModel {
[Required]
[EmailAddress]
public string Email { get; set; }
[Required]
[DataType(DataType.Password)]
public string Password { get; set; }
[Display(Name = "Remember me?")]
public bool RememberMe { get; set; }
}
public async Task OnGetAsync(string returnUrl)
{
if (!string.IsNullOrEmpty(ErrorMessage)) {
ModelState.AddModelError(string.Empty, ErrorMessage);
}
returnUrl = returnUrl ?? Url.Content("~/");
// Clear the existing external cookie to ensure a clean login process
await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
ReturnUrl = returnUrl;
}
public async Task < IActionResult > OnPostAsync(string returnUrl)
{
returnUrl = returnUrl ?? Url.Content("~/");
if (ModelState.IsValid) {
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, set lockoutOnFailure: true
var result = await _signInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: false);
if (result.Succeeded) {
_logger.LogInformation("User logged in.");
return LocalRedirect(returnUrl);
}
if (result.RequiresTwoFactor) {
return RedirectToPage("./LoginWith2fa", new { ReturnUrl = returnUrl, RememberMe = Input.RememberMe });
}
if (result.IsLockedOut) {
_logger.LogWarning("User account locked out.");
return RedirectToPage("./Lockout");
}
else {
ModelState.AddModelError(string.Empty, "Invalid login attempt.");
return Page();
}
}
// If we got this far, something failed, redisplay form
return Page();
}
}
_LoginPartial.cshtml
@using Microsoft.AspNetCore.Identity
@inject SignInManager < ApplicationUser > SignInManager
@inject UserManager < ApplicationUser > UserManager
< ul class="navbar-nav" >
@if (SignInManager.IsSignedIn(User))
{
<li class="nav-item">
<a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Manage/Index" title="Manage">Hello @User.Identity.Name!</a>
</li>
<li class="nav-item">
<form class="form-inline" asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="@Model.ReturnUrl">
<button type="submit" class="nav-link btn btn-link text-dark">Logout</button>
</form>
</li >
}
else
{
<li class="nav-item">
<a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Register" asp-route-returnUrl="@Model.ReturnUrl">Register</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Login" asp-route-returnUrl="@Model.ReturnUrl">Login</a>
</li>
}
</ul >
HomeController.cs
[...]
public IActionResult Index(string GB)
{
if (string.IsNullOrEmpty(GB)) {
return RedirectPermanent("Error");
}
return View();
}
[...]
Ok I got it & it works.
Updates :
HomeController.cs
[...]
public IActionResult Index(string GB)
{
ViewBag.GB = GB;
if (string.IsNullOrEmpty(GB)) {
return RedirectPermanent("Error");
}
return View();
}
[...]
_LoginPartial.cshtml
@using Microsoft.AspNetCore.Identity
@inject SignInManager < ApplicationUser > SignInManager
@inject UserManager < ApplicationUser > UserManager
< ul class="navbar-nav" >
@if (SignInManager.IsSignedIn(User))
{
<li class="nav-item">
<a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Manage/Index" title="Manage">Hello @User.Identity.Name!</a>
</li>
<li class="nav-item">
@if (Model != null && !string.IsNullOrEmpty(Model.FirstName))
{
<form class="form-inline" asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="@Model.ReturnUrl">
<button type="submit" class="nav-link btn btn-link text-dark">Logout</button>
</form>
}
else
{
<form class="form-inline" asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="@ViewBag.GB">
<button type="submit" class="nav-link btn btn-link text-dark">Logout</button>
</form>
}
</li >
}
else
{
<li class="nav-item">
<a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Register" asp-route-returnUrl="@Model.ReturnUrl">Register</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Login" asp-route-returnUrl="@Model.ReturnUrl">Login</a>
</li>
}
</ul>