Browse Source

Merge pull request #22573 from abpframework/auto-merge/rel-9-2/3614

Merge branch dev with rel-9.2
pull/22579/head
maliming 1 year ago
committed by GitHub
parent
commit
f3075ff169
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 101
      modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/Controllers/AuthorizeController.cs

101
modules/openiddict/src/Volo.Abp.OpenIddict.AspNetCore/Volo/Abp/OpenIddict/Controllers/AuthorizeController.cs

@ -11,7 +11,6 @@ using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Microsoft.Extensions.Primitives;
using OpenIddict.Abstractions; using OpenIddict.Abstractions;
using OpenIddict.Server.AspNetCore; using OpenIddict.Server.AspNetCore;
using Volo.Abp.AspNetCore.Security; using Volo.Abp.AspNetCore.Security;
@ -31,52 +30,22 @@ public class AuthorizeController : AbpOpenIdDictControllerBase
{ {
var request = await GetOpenIddictServerRequestAsync(HttpContext); var request = await GetOpenIddictServerRequestAsync(HttpContext);
// If prompt=login was specified by the client application, // Try to retrieve the user principal stored in the authentication cookie and redirect
// immediately return the user agent to the login page. // the user agent to the login page (or to an external provider) in the following cases:
if (request.HasPromptValue(OpenIddictConstants.PromptValues.Login)) //
{ // - If the user principal can't be extracted or the cookie is too old.
// To avoid endless login -> authorization redirects, the prompt=login flag // - If prompt=login was specified by the client application.
// is removed from the authorization request payload before redirecting the user. // - If max_age=0 was specified by the client application (max_age=0 is equivalent to prompt=login).
var prompt = string.Join(" ", request.GetPromptValues().Remove(OpenIddictConstants.PromptValues.Login)); // - If a max_age parameter was provided and the authentication cookie is not considered "fresh" enough.
//
var parameters = Request.HasFormContentType ? // For scenarios where the default authentication handler configured in the ASP.NET Core
Request.Form.Where(parameter => parameter.Key != OpenIddictConstants.Parameters.Prompt).ToList() : // authentication options shouldn't be used, a specific scheme can be specified here.
Request.Query.Where(parameter => parameter.Key != OpenIddictConstants.Parameters.Prompt).ToList();
parameters.Add(KeyValuePair.Create(OpenIddictConstants.Parameters.Prompt, new StringValues(prompt)));
return Challenge(
authenticationSchemes: IdentityConstants.ApplicationScheme,
properties: new AuthenticationProperties
{
RedirectUri = Request.PathBase + Request.Path + QueryString.Create(parameters)
});
}
// 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<IOptions<AbpOpenIddictAspNetCoreOptions>>().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.
var result = await HttpContext.AuthenticateAsync(IdentityConstants.ApplicationScheme); var result = await HttpContext.AuthenticateAsync(IdentityConstants.ApplicationScheme);
if (result == null || !result.Succeeded || (request.MaxAge != null && result.Properties?.IssuedUtc != null && if (result is not { Succeeded: true } ||
DateTimeOffset.UtcNow - result.Properties.IssuedUtc > TimeSpan.FromSeconds(request.MaxAge.Value))) ((request.HasPromptValue(OpenIddictConstants.PromptValues.Login) || request.MaxAge is 0 ||
(request.MaxAge != null && result.Properties?.IssuedUtc != null &&
TimeProvider.System.GetUtcNow() - result.Properties.IssuedUtc > TimeSpan.FromSeconds(request.MaxAge.Value))) &&
TempData["IgnoreAuthenticationChallenge"] is null or false))
{ {
// If the client application requested promptless authentication, // If the client application requested promptless authentication,
// return an error indicating that the user is not logged in. // return an error indicating that the user is not logged in.
@ -91,13 +60,33 @@ public class AuthorizeController : AbpOpenIdDictControllerBase
})); }));
} }
return Challenge( // To avoid endless login endpoint -> authorization endpoint redirects, a special temp data entry is
authenticationSchemes: IdentityConstants.ApplicationScheme, // used to skip the challenge if the user agent has already been redirected to the login endpoint.
properties: new AuthenticationProperties //
{ // Note: this flag doesn't guarantee that the user has accepted to re-authenticate. If such a guarantee
RedirectUri = Request.PathBase + Request.Path + QueryString.Create( // is needed, the existing authentication cookie MUST be deleted AND revoked (e.g using ASP.NET Core
Request.HasFormContentType ? Request.Form.ToList() : Request.Query.ToList()) // Identity's security stamp feature with an extremely short revalidation time span) before triggering
}); // a challenge to redirect the user agent to the login endpoint.
TempData["IgnoreAuthenticationChallenge"] = true;
// For scenarios where the default challenge handler configured in the ASP.NET Core
// authentication options shouldn't be used, a specific scheme can be specified here.
return Challenge(new AuthenticationProperties
{
RedirectUri = Request.PathBase + Request.Path + QueryString.Create(Request.HasFormContentType ? Request.Form : Request.Query)
});
}
// 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) && TempData["IgnoreSelectAccount"] is null or false)
{
// To avoid endless select account endpoint -> authorization endpoint redirects, a special temp data entry is
// used to skip the redirect if the user agent has already been redirected to the select account endpoint.
TempData["IgnoreSelectAccount"] = true;
var selectAccountPath = HttpContext.RequestServices.GetRequiredService<IOptions<AbpOpenIddictAspNetCoreOptions>>().Value.SelectAccountPage.RemovePostFix("/");
return Redirect(Url.Content($"{selectAccountPath}?RedirectUri={UrlEncoder.Default.Encode(Request.PathBase + Request.Path + QueryString.Create(Request.HasFormContentType ? Request.Form : Request.Query))}"));
} }
// Retrieve the profile of the logged in user. // Retrieve the profile of the logged in user.
@ -111,8 +100,7 @@ public class AuthorizeController : AbpOpenIdDictControllerBase
authenticationSchemes: IdentityConstants.ApplicationScheme, authenticationSchemes: IdentityConstants.ApplicationScheme,
properties: new AuthenticationProperties properties: new AuthenticationProperties
{ {
RedirectUri = Request.PathBase + Request.Path + QueryString.Create( RedirectUri = Request.PathBase + Request.Path + QueryString.Create(Request.HasFormContentType ? Request.Form : Request.Query)
Request.HasFormContentType ? Request.Form.ToList() : Request.Query.ToList())
}); });
} }
} }
@ -124,8 +112,7 @@ public class AuthorizeController : AbpOpenIdDictControllerBase
authenticationSchemes: IdentityConstants.ApplicationScheme, authenticationSchemes: IdentityConstants.ApplicationScheme,
properties: new AuthenticationProperties properties: new AuthenticationProperties
{ {
RedirectUri = Request.PathBase + Request.Path + QueryString.Create( RedirectUri = Request.PathBase + Request.Path + QueryString.Create(Request.HasFormContentType ? Request.Form : Request.Query)
Request.HasFormContentType ? Request.Form.ToList() : Request.Query.ToList())
}); });
} }

Loading…
Cancel
Save