Browse Source

Identity Server: When click on logo redirects to original application instead of identity home

pull/49/merge
Carlos Cañizares Estévez 8 years ago
parent
commit
5fc53dcad2
7 changed files with 65 additions and 362 deletions
  1. +3
    -0
      src/Services/Identity/eShopOnContainers.Identity/Controllers/ConsentController.cs
  2. +12
    -1
      src/Services/Identity/eShopOnContainers.Identity/Controllers/HomeController.cs
  3. +0
    -360
      src/Services/Identity/eShopOnContainers.Identity/Controllers/ManageController.cs
  4. +12
    -0
      src/Services/Identity/eShopOnContainers.Identity/Services/IRedirectService.cs
  5. +36
    -0
      src/Services/Identity/eShopOnContainers.Identity/Services/RedirectService.cs
  6. +1
    -0
      src/Services/Identity/eShopOnContainers.Identity/Startup.cs
  7. +1
    -1
      src/Services/Identity/eShopOnContainers.Identity/Views/Shared/_Layout.cshtml

+ 3
- 0
src/Services/Identity/eShopOnContainers.Identity/Controllers/ConsentController.cs View File

@ -11,6 +11,7 @@ using IdentityServer4.Models;
using IdentityServer4.Stores;
using IdentityServer4.Quickstart.UI.Models;
using eShopOnContainers.Identity.Models.AccountViewModels;
using eShopOnContainers.Identity.Services;
namespace IdentityServer4.Quickstart.UI.Controllers
{
@ -23,6 +24,7 @@ namespace IdentityServer4.Quickstart.UI.Controllers
private readonly IClientStore _clientStore;
private readonly IScopeStore _scopeStore;
private readonly IIdentityServerInteractionService _interaction;
public ConsentController(
ILogger<ConsentController> logger,
@ -45,6 +47,7 @@ namespace IdentityServer4.Quickstart.UI.Controllers
public async Task<IActionResult> Index(string returnUrl)
{
var vm = await BuildViewModelAsync(returnUrl);
ViewData["ReturnUrl"] = returnUrl;
if (vm != null)
{
return View("Index", vm);


+ 12
- 1
src/Services/Identity/eShopOnContainers.Identity/Controllers/HomeController.cs View File

@ -3,6 +3,7 @@
using eShopOnContainers.Identity;
using eShopOnContainers.Identity.Services;
using IdentityServer4.Quickstart.UI.Models;
using IdentityServer4.Services;
using Microsoft.AspNetCore.Mvc;
@ -15,11 +16,13 @@ namespace IdentityServer4.Quickstart.UI.Controllers
{
private readonly IIdentityServerInteractionService _interaction;
private readonly IOptions<AppSettings> _settings;
private readonly IRedirectService _redirectSvc;
public HomeController(IIdentityServerInteractionService interaction, IOptions<AppSettings> settings)
public HomeController(IIdentityServerInteractionService interaction, IOptions<AppSettings> settings,IRedirectService redirectSvc)
{
_interaction = interaction;
_settings = settings;
_redirectSvc = redirectSvc;
}
public IActionResult Index(string returnUrl)
@ -27,6 +30,14 @@ namespace IdentityServer4.Quickstart.UI.Controllers
return View();
}
public IActionResult ReturnToOriginalApplication(string returnUrl)
{
if (returnUrl != null)
return Redirect(_redirectSvc.ExtractRedirectUriFromReturnUrl(returnUrl));
else
return RedirectToAction("Index", "Home");
}
/// <summary>
/// Shows the error page
/// </summary>


+ 0
- 360
src/Services/Identity/eShopOnContainers.Identity/Controllers/ManageController.cs View File

@ -1,360 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using eShopOnContainers.Identity.Models;
using eShopOnContainers.Identity.Models.ManageViewModels;
using eShopOnContainers.Identity.Services;
namespace eShopOnContainers.Identity.Controllers
{
[Authorize]
public class ManageController : Controller
{
private readonly UserManager<ApplicationUser> _userManager;
private readonly SignInManager<ApplicationUser> _signInManager;
private readonly IEmailSender _emailSender;
private readonly ISmsSender _smsSender;
private readonly ILogger _logger;
public ManageController(
UserManager<ApplicationUser> userManager,
SignInManager<ApplicationUser> signInManager,
IEmailSender emailSender,
ISmsSender smsSender,
ILoggerFactory loggerFactory)
{
_userManager = userManager;
_signInManager = signInManager;
_emailSender = emailSender;
_smsSender = smsSender;
_logger = loggerFactory.CreateLogger<ManageController>();
}
//
// GET: /Manage/Index
[HttpGet]
public async Task<IActionResult> Index(ManageMessageId? message = null)
{
ViewData["StatusMessage"] =
message == ManageMessageId.ChangePasswordSuccess ? "Your password has been changed."
: message == ManageMessageId.SetPasswordSuccess ? "Your password has been set."
: message == ManageMessageId.SetTwoFactorSuccess ? "Your two-factor authentication provider has been set."
: message == ManageMessageId.Error ? "An error has occurred."
: message == ManageMessageId.AddPhoneSuccess ? "Your phone number was added."
: message == ManageMessageId.RemovePhoneSuccess ? "Your phone number was removed."
: "";
var user = await GetCurrentUserAsync();
if (user == null)
{
return View("Error");
}
var model = new IndexViewModel
{
HasPassword = await _userManager.HasPasswordAsync(user),
PhoneNumber = await _userManager.GetPhoneNumberAsync(user),
TwoFactor = await _userManager.GetTwoFactorEnabledAsync(user),
Logins = await _userManager.GetLoginsAsync(user),
BrowserRemembered = await _signInManager.IsTwoFactorClientRememberedAsync(user)
};
return View(model);
}
//
// POST: /Manage/RemoveLogin
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> RemoveLogin(RemoveLoginViewModel account)
{
ManageMessageId? message = ManageMessageId.Error;
var user = await GetCurrentUserAsync();
if (user != null)
{
var result = await _userManager.RemoveLoginAsync(user, account.LoginProvider, account.ProviderKey);
if (result.Succeeded)
{
await _signInManager.SignInAsync(user, isPersistent: false);
message = ManageMessageId.RemoveLoginSuccess;
}
}
return RedirectToAction(nameof(ManageLogins), new { Message = message });
}
//
// GET: /Manage/AddPhoneNumber
public IActionResult AddPhoneNumber()
{
return View();
}
//
// POST: /Manage/AddPhoneNumber
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> AddPhoneNumber(AddPhoneNumberViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
// Generate the token and send it
var user = await GetCurrentUserAsync();
if (user == null)
{
return View("Error");
}
var code = await _userManager.GenerateChangePhoneNumberTokenAsync(user, model.PhoneNumber);
await _smsSender.SendSmsAsync(model.PhoneNumber, "Your security code is: " + code);
return RedirectToAction(nameof(VerifyPhoneNumber), new { PhoneNumber = model.PhoneNumber });
}
//
// POST: /Manage/EnableTwoFactorAuthentication
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> EnableTwoFactorAuthentication()
{
var user = await GetCurrentUserAsync();
if (user != null)
{
await _userManager.SetTwoFactorEnabledAsync(user, true);
await _signInManager.SignInAsync(user, isPersistent: false);
_logger.LogInformation(1, "User enabled two-factor authentication.");
}
return RedirectToAction(nameof(Index), "Manage");
}
//
// POST: /Manage/DisableTwoFactorAuthentication
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DisableTwoFactorAuthentication()
{
var user = await GetCurrentUserAsync();
if (user != null)
{
await _userManager.SetTwoFactorEnabledAsync(user, false);
await _signInManager.SignInAsync(user, isPersistent: false);
_logger.LogInformation(2, "User disabled two-factor authentication.");
}
return RedirectToAction(nameof(Index), "Manage");
}
//
// GET: /Manage/VerifyPhoneNumber
[HttpGet]
public async Task<IActionResult> VerifyPhoneNumber(string phoneNumber)
{
var user = await GetCurrentUserAsync();
if (user == null)
{
return View("Error");
}
var code = await _userManager.GenerateChangePhoneNumberTokenAsync(user, phoneNumber);
// Send an SMS to verify the phone number
return phoneNumber == null ? View("Error") : View(new VerifyPhoneNumberViewModel { PhoneNumber = phoneNumber });
}
//
// POST: /Manage/VerifyPhoneNumber
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> VerifyPhoneNumber(VerifyPhoneNumberViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
var user = await GetCurrentUserAsync();
if (user != null)
{
var result = await _userManager.ChangePhoneNumberAsync(user, model.PhoneNumber, model.Code);
if (result.Succeeded)
{
await _signInManager.SignInAsync(user, isPersistent: false);
return RedirectToAction(nameof(Index), new { Message = ManageMessageId.AddPhoneSuccess });
}
}
// If we got this far, something failed, redisplay the form
ModelState.AddModelError(string.Empty, "Failed to verify phone number");
return View(model);
}
//
// POST: /Manage/RemovePhoneNumber
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> RemovePhoneNumber()
{
var user = await GetCurrentUserAsync();
if (user != null)
{
var result = await _userManager.SetPhoneNumberAsync(user, null);
if (result.Succeeded)
{
await _signInManager.SignInAsync(user, isPersistent: false);
return RedirectToAction(nameof(Index), new { Message = ManageMessageId.RemovePhoneSuccess });
}
}
return RedirectToAction(nameof(Index), new { Message = ManageMessageId.Error });
}
//
// GET: /Manage/ChangePassword
[HttpGet]
public IActionResult ChangePassword()
{
return View();
}
//
// POST: /Manage/ChangePassword
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> ChangePassword(ChangePasswordViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
var user = await GetCurrentUserAsync();
if (user != null)
{
var result = await _userManager.ChangePasswordAsync(user, model.OldPassword, model.NewPassword);
if (result.Succeeded)
{
await _signInManager.SignInAsync(user, isPersistent: false);
_logger.LogInformation(3, "User changed their password successfully.");
return RedirectToAction(nameof(Index), new { Message = ManageMessageId.ChangePasswordSuccess });
}
AddErrors(result);
return View(model);
}
return RedirectToAction(nameof(Index), new { Message = ManageMessageId.Error });
}
//
// GET: /Manage/SetPassword
[HttpGet]
public IActionResult SetPassword()
{
return View();
}
//
// POST: /Manage/SetPassword
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> SetPassword(SetPasswordViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
var user = await GetCurrentUserAsync();
if (user != null)
{
var result = await _userManager.AddPasswordAsync(user, model.NewPassword);
if (result.Succeeded)
{
await _signInManager.SignInAsync(user, isPersistent: false);
return RedirectToAction(nameof(Index), new { Message = ManageMessageId.SetPasswordSuccess });
}
AddErrors(result);
return View(model);
}
return RedirectToAction(nameof(Index), new { Message = ManageMessageId.Error });
}
//GET: /Manage/ManageLogins
[HttpGet]
public async Task<IActionResult> ManageLogins(ManageMessageId? message = null)
{
ViewData["StatusMessage"] =
message == ManageMessageId.RemoveLoginSuccess ? "The external login was removed."
: message == ManageMessageId.AddLoginSuccess ? "The external login was added."
: message == ManageMessageId.Error ? "An error has occurred."
: "";
var user = await GetCurrentUserAsync();
if (user == null)
{
return View("Error");
}
var userLogins = await _userManager.GetLoginsAsync(user);
var otherLogins = _signInManager.GetExternalAuthenticationSchemes().Where(auth => userLogins.All(ul => auth.AuthenticationScheme != ul.LoginProvider)).ToList();
ViewData["ShowRemoveButton"] = user.PasswordHash != null || userLogins.Count > 1;
return View(new ManageLoginsViewModel
{
CurrentLogins = userLogins,
OtherLogins = otherLogins
});
}
//
// POST: /Manage/LinkLogin
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult LinkLogin(string provider)
{
// Request a redirect to the external login provider to link a login for the current user
var redirectUrl = Url.Action("LinkLoginCallback", "Manage");
var properties = _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl, _userManager.GetUserId(User));
return Challenge(properties, provider);
}
//
// GET: /Manage/LinkLoginCallback
[HttpGet]
public async Task<ActionResult> LinkLoginCallback()
{
var user = await GetCurrentUserAsync();
if (user == null)
{
return View("Error");
}
var info = await _signInManager.GetExternalLoginInfoAsync(await _userManager.GetUserIdAsync(user));
if (info == null)
{
return RedirectToAction(nameof(ManageLogins), new { Message = ManageMessageId.Error });
}
var result = await _userManager.AddLoginAsync(user, info);
var message = result.Succeeded ? ManageMessageId.AddLoginSuccess : ManageMessageId.Error;
return RedirectToAction(nameof(ManageLogins), new { Message = message });
}
#region Helpers
private void AddErrors(IdentityResult result)
{
foreach (var error in result.Errors)
{
ModelState.AddModelError(string.Empty, error.Description);
}
}
public enum ManageMessageId
{
AddPhoneSuccess,
AddLoginSuccess,
ChangePasswordSuccess,
SetTwoFactorSuccess,
SetPasswordSuccess,
RemoveLoginSuccess,
RemovePhoneSuccess,
Error
}
private Task<ApplicationUser> GetCurrentUserAsync()
{
return _userManager.GetUserAsync(HttpContext.User);
}
#endregion
}
}

+ 12
- 0
src/Services/Identity/eShopOnContainers.Identity/Services/IRedirectService.cs View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace eShopOnContainers.Identity.Services
{
public interface IRedirectService
{
string ExtractRedirectUriFromReturnUrl(string url);
}
}

+ 36
- 0
src/Services/Identity/eShopOnContainers.Identity/Services/RedirectService.cs View File

@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace eShopOnContainers.Identity.Services
{
public class RedirectService : IRedirectService
{
public string ExtractRedirectUriFromReturnUrl(string url)
{
var result = "";
var decodedUrl = System.Net.WebUtility.HtmlDecode(url);
var results = Regex.Split(decodedUrl, "redirect_uri=");
if (results.Length < 2)
return "";
result = results[1];
var splitKey = "";
if (result.Contains("signin-oidc"))
splitKey = "signin-oidc";
else
splitKey = "scope";
results = Regex.Split(result, splitKey);
if (results.Length < 2)
return "";
result = results[0];
return result.Replace("%3A", ":").Replace("%2F", "/").Replace("&", "");
}
}
}

+ 1
- 0
src/Services/Identity/eShopOnContainers.Identity/Startup.cs View File

@ -59,6 +59,7 @@ namespace eShopOnContainers.Identity
services.AddTransient<IEmailSender, AuthMessageSender>();
services.AddTransient<ISmsSender, AuthMessageSender>();
services.AddTransient<ILoginService<ApplicationUser>, EFLoginService>();
services.AddTransient<IRedirectService, RedirectService>();
//callbacks urls from config:
Dictionary<string, string> clientUrls = new Dictionary<string, string>();


+ 1
- 1
src/Services/Identity/eShopOnContainers.Identity/Views/Shared/_Layout.cshtml View File

@ -14,7 +14,7 @@
<div class="container">
<div class="row">
<div class="navbar-header col-sm-6 col-xs-8">
<a href="~/">
<a asp-controller="home" asp-action="ReturnToOriginalApplication" asp-route-returnUrl="@ViewData["ReturnUrl"]">
<div class="navbar-brand"></div>
</a>
</div>


Loading…
Cancel
Save