diff --git a/modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/AbpOpenIddictOptions.cs b/modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/AbpOpenIddictOptions.cs
index 84149e9b0b..3339b6d376 100644
--- a/modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/AbpOpenIddictOptions.cs
+++ b/modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/AbpOpenIddictOptions.cs
@@ -20,4 +20,9 @@ public class AbpOpenIddictAspNetCoreOptions
/// Attach auth server current culture info to response.
///
public bool AttachCultureInfo { get; set; } = true;
+
+ ///
+ /// Set the url of the select account page.
+ ///
+ public string SelectAccountPage { get; set; } = "~/Account/SelectAccount";
}
diff --git a/modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/Controllers/AuthorizeController.cs b/modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/Controllers/AuthorizeController.cs
index f61d6fde45..b575a03c0e 100644
--- a/modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/Controllers/AuthorizeController.cs
+++ b/modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/Controllers/AuthorizeController.cs
@@ -2,12 +2,15 @@
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
+using System.Text.Encodings.Web;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Options;
using Microsoft.Extensions.Primitives;
using OpenIddict.Abstractions;
using OpenIddict.Server.AspNetCore;
@@ -50,6 +53,24 @@ public class AuthorizeController : AbpOpenIdDictControllerBase
});
}
+ // If prompt=select_account was specified by the client application,
+ // We will redirect the user to the select_account page.
+ if (request.HasPromptValue(OpenIddictConstants.PromptValues.SelectAccount))
+ {
+ // To avoid endless login -> authorization redirects, the prompt=login flag
+ // is removed from the authorization request payload before redirecting the user.
+ var prompt = string.Join(" ", request.GetPromptValues().Remove(OpenIddictConstants.PromptValues.SelectAccount));
+
+ var parameters = Request.HasFormContentType ?
+ Request.Form.Where(parameter => parameter.Key != OpenIddictConstants.Parameters.Prompt).ToList() :
+ Request.Query.Where(parameter => parameter.Key != OpenIddictConstants.Parameters.Prompt).ToList();
+
+ parameters.Add(KeyValuePair.Create(OpenIddictConstants.Parameters.Prompt, new StringValues(prompt)));
+
+ var selectAccountPath = HttpContext.RequestServices.GetRequiredService>().Value.SelectAccountPage;
+ return Redirect(Url.Content($"{selectAccountPath}?RedirectUri={UrlEncoder.Default.Encode(Request.PathBase + Request.Path + QueryString.Create(parameters))}"));
+ }
+
// Retrieve the user principal stored in the authentication cookie.
// If a max_age parameter was provided, ensure that the cookie is not too old.
// If the user principal can't be extracted or the cookie is too old, redirect the user to the login page.