diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Authentication/ChallengeAccountController.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Authentication/ChallengeAccountController.cs new file mode 100644 index 0000000000..de8958920d --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Authentication/ChallengeAccountController.cs @@ -0,0 +1,85 @@ +using System; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Mvc; + +namespace Volo.Abp.AspNetCore.Mvc.Authentication +{ + public abstract class ChallengeAccountController : AbpController + { + protected string[] ChallengeAuthenticationSchemas { get; } + + protected ChallengeAccountController(string[] challengeAuthenticationSchemas = null) + { + ChallengeAuthenticationSchemas = challengeAuthenticationSchemas ?? new[]{ "oidc" }; + } + + [HttpGet] + public ActionResult Login(string returnUrl = "", string returnUrlHash = "") + { + if (CurrentUser.IsAuthenticated) + { + return RedirectSafely(returnUrl, returnUrlHash); + } + else + { + return Challenge( + new AuthenticationProperties + { + Parameters = + { + {"returnUrl", returnUrl}, + {"returnUrlHash", returnUrlHash} + } + }, + ChallengeAuthenticationSchemas + ); + } + } + + [HttpGet] + public async Task Logout(string returnUrl = "", string returnUrlHash = "") + { + await HttpContext.SignOutAsync(); + + return RedirectSafely(returnUrl, returnUrlHash); + } + + protected RedirectResult RedirectSafely(string returnUrl, string returnUrlHash = null) + { + return Redirect(GetRedirectUrl(returnUrl, returnUrlHash)); + } + + private string GetRedirectUrl(string returnUrl, string returnUrlHash = null) + { + returnUrl = NormalizeReturnUrl(returnUrl); + + if (!returnUrlHash.IsNullOrWhiteSpace()) + { + returnUrl = returnUrl + returnUrlHash; + } + + return returnUrl; + } + + private string NormalizeReturnUrl(string returnUrl) + { + if (returnUrl.IsNullOrEmpty()) + { + return GetAppHomeUrl(); + } + + if (Url.IsLocalUrl(returnUrl)) + { + return returnUrl; + } + + return GetAppHomeUrl(); + } + + protected virtual string GetAppHomeUrl() + { + return "/"; + } + } +} \ No newline at end of file diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web.Host/Controllers/AccountController.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web.Host/Controllers/AccountController.cs new file mode 100644 index 0000000000..29fa140e4d --- /dev/null +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web.Host/Controllers/AccountController.cs @@ -0,0 +1,9 @@ +using Volo.Abp.AspNetCore.Mvc.Authentication; + +namespace MyCompanyName.MyProjectName.Web.Controllers +{ + public class AccountController : ChallengeAccountController + { + + } +} \ No newline at end of file diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web.Host/Menus/MyProjectNameMenuContributor.cs b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web.Host/Menus/MyProjectNameMenuContributor.cs index 5f158525f3..17162b42c7 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web.Host/Menus/MyProjectNameMenuContributor.cs +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web.Host/Menus/MyProjectNameMenuContributor.cs @@ -16,9 +16,13 @@ namespace MyCompanyName.MyProjectName.Web.Menus { await ConfigureMainMenuAsync(context); } + else if (context.Menu.Name == StandardMenus.User) + { + await ConfigureUserMenuAsync(context); + } } - private async Task ConfigureMainMenuAsync(MenuConfigurationContext context) + private Task ConfigureMainMenuAsync(MenuConfigurationContext context) { if (!MultiTenancyConsts.IsEnabled) { @@ -29,6 +33,17 @@ namespace MyCompanyName.MyProjectName.Web.Menus var l = context.ServiceProvider.GetRequiredService>(); context.Menu.Items.Insert(0, new ApplicationMenuItem("MyProjectName.Home", l["Menu:Home"], "/")); + + return Task.CompletedTask; + } + + private Task ConfigureUserMenuAsync(MenuConfigurationContext context) + { + var l = context.ServiceProvider.GetRequiredService>(); + + context.Menu.AddItem(new ApplicationMenuItem("Account.Logout", l["Logout"], url: "/Account/Logout", icon: "fa fa-power-off", order: int.MaxValue - 1000)); + + return Task.CompletedTask; } } }