Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A website uses openid to access B website (Orchard core) to fix the i… #16921

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ public async Task<IActionResult> Index(EnableAuthenticatorViewModel model)

await Notifier.SuccessAsync(H["Your authenticator app has been verified."]);

return await RedirectToTwoFactorAsync(user);
return await RedirectToTwoFactorAsync(user,model.ReturnUrl);
}

public async Task<IActionResult> Reset()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,10 +140,10 @@ public async Task<IActionResult> IndexPost(RequestCodeSmsAuthenticatorViewModel

await SetPendingPhoneNumberAsync(phoneNumber, user.UserName);

return RedirectToAction(nameof(ValidateCode));
return RedirectToAction(nameof(ValidateCode),new { model.ReturnUrl });
}

public async Task<IActionResult> ValidateCode()
public async Task<IActionResult> ValidateCode(string returnUrl=null)
{
var user = await UserManager.GetUserAsync(User);
if (user == null)
Expand All @@ -159,7 +159,7 @@ public async Task<IActionResult> ValidateCode()

return RedirectToAction(nameof(Index));
}

ViewData["ReturnUrl"] = returnUrl;
var model = new EnableSmsAuthenticatorViewModel
{
PhoneNumber = pendingPhoneNumber,
Expand Down Expand Up @@ -193,7 +193,7 @@ public async Task<IActionResult> ValidateCode(EnableSmsAuthenticatorViewModel mo

await Notifier.SuccessAsync(H["Your phone number has been confirmed."]);

return await RedirectToTwoFactorAsync(user);
return await RedirectToTwoFactorAsync(user,model.ReturnUrl);
}

await Notifier.ErrorAsync(H["Invalid verification code."]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ protected async Task RefreshTwoFactorClaimAsync(IUser user)
}
}

protected async Task<IActionResult> RedirectToTwoFactorAsync(IUser user)
protected async Task<IActionResult> RedirectToTwoFactorAsync(IUser user, string returnUrl=null)
{
if (await UserManager.CountRecoveryCodesAsync(user) == 0)
{
Expand All @@ -142,12 +142,13 @@ protected async Task<IActionResult> RedirectToTwoFactorAsync(IUser user)

await Notifier.WarningAsync(H["New recovery codes were generated."]);

return RedirectToAction(nameof(TwoFactorAuthenticationController.ShowRecoveryCodes), _twoFactorAuthenticationControllerName);
// 传递 returnUrl 参数
return RedirectToAction(nameof(TwoFactorAuthenticationController.ShowRecoveryCodes), _twoFactorAuthenticationControllerName, new { returnUrl });
}

// 如果不需要生成新的恢复码,则直接重定向到 TwoFactorIndex
return RedirectToTwoFactorIndex();
}

protected async Task<IList<string>> GetTwoFactorProvidersAsync(IUser user)
{
var providers = await UserManager.GetValidTwoFactorProvidersAsync(user);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ public async Task<IActionResult> LoginWithRecoveryCode(LoginWithRecoveryCodeView
return View(model);
}

public async Task<IActionResult> Index()
public async Task<IActionResult> Index(string returnUrl=null)
{
var user = await UserManager.GetUserAsync(User);
if (user == null)
Expand All @@ -223,18 +223,20 @@ public async Task<IActionResult> Index()

var providers = await GetTwoFactorProvidersAsync(user);
var model = new TwoFactorAuthenticationViewModel();
await PopulateModelAsync(user, providers, model);

await PopulateModelAsync(user, providers, model,returnUrl);

if (user is User u)
{
model.PreferredProvider = u.As<TwoFactorPreference>().DefaultProvider;
}

ViewData["ReturnUrl"] = returnUrl;
//RedirectToLocal(returnUrl);
return View(model);
}

[HttpPost]
public async Task<IActionResult> Index(TwoFactorAuthenticationViewModel model)
public async Task<IActionResult> Index(TwoFactorAuthenticationViewModel model, string returnUrl = null)
{
var user = await UserManager.GetUserAsync(User);
if (user == null)
Expand All @@ -257,14 +259,27 @@ public async Task<IActionResult> Index(TwoFactorAuthenticationViewModel model)

await Notifier.SuccessAsync(H["Preferences were updated successfully."]);

return RedirectToAction(nameof(Index));
// 优先使用提供的 returnUrl,如果没有提供则重定向到 Index
if (!string.IsNullOrEmpty(returnUrl) && Url.IsLocalUrl(returnUrl))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction(nameof(Index));
}
//return RedirectToAction(nameof(Index));
}

await Notifier.ErrorAsync(H["Unable to update preferences."]);
}

await PopulateModelAsync(user, providers, model);

// 如果有 returnUrl,将其传递给视图
if (!string.IsNullOrEmpty(returnUrl))
{
ViewData["ReturnUrl"] = returnUrl;
}
return View(model);
}

Expand Down Expand Up @@ -328,7 +343,7 @@ public async Task<IActionResult> GenerateRecoveryCodesPost()
return RedirectToAction(nameof(ShowRecoveryCodes));
}

public async Task<IActionResult> ShowRecoveryCodes()
public async Task<IActionResult> ShowRecoveryCodes(string returnUrl=null)
{
var user = await UserManager.GetUserAsync(User);
if (user == null)
Expand All @@ -339,7 +354,10 @@ public async Task<IActionResult> ShowRecoveryCodes()
var userId = await UserManager.GetUserIdAsync(user);

var recoveryCodes = await GetCachedRecoveryCodesAsync(userId);

if(Url.IsLocalUrl(returnUrl))
{
return Redirect(returnUrl);
}
if (recoveryCodes == null || recoveryCodes.Length == 0)
{
return RedirectToAction(nameof(Index));
Expand Down Expand Up @@ -474,7 +492,7 @@ private static string GetProvider(IList<string> providers, IUser user, string pr
return defaultProvider;
}

private async Task PopulateModelAsync(IUser user, IList<string> providers, TwoFactorAuthenticationViewModel model)
private async Task PopulateModelAsync(IUser user, IList<string> providers, TwoFactorAuthenticationViewModel model,string returnUrl="")
{
model.User = user;
model.IsTwoFaEnabled = await UserManager.GetTwoFactorEnabledAsync(user);
Expand All @@ -489,6 +507,7 @@ private async Task PopulateModelAsync(IUser user, IList<string> providers, TwoFa
{
Provider = key,
IsEnabled = providers.Contains(key),
ReturnUrl = returnUrl
};

var shape = await _twoFactorDisplayManager.BuildDisplayAsync(method, this, "SummaryAdmin");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,27 @@ public override IDisplayResult Display(TwoFactorMethod model, BuildDisplayContex
{
return null;
}

// 从上下文中获取 returnUrl 参数

var icon = Initialize<TwoFactorMethod>($"TwoFactorMethod_{model.Provider}_Icon", vm =>
{
vm.Provider = model.Provider;
vm.IsEnabled = model.IsEnabled;
vm.ReturnUrl = model.ReturnUrl; // 传递 returnUrl 参数
}).Location("SummaryAdmin", "Icon");

var content = Initialize<TwoFactorMethod>($"TwoFactorMethod_{model.Provider}_Content", vm =>
{
vm.Provider = model.Provider;
vm.IsEnabled = model.IsEnabled;
vm.ReturnUrl = model.ReturnUrl; // 传递 returnUrl 参数
}).Location("SummaryAdmin", "Content");

var actions = Initialize<TwoFactorMethod>($"TwoFactorMethod_{model.Provider}_Actions", vm =>
{
vm.Provider = model.Provider;
vm.IsEnabled = model.IsEnabled;
vm.ReturnUrl = model.ReturnUrl; // 传递 returnUrl 参数
}).Location("SummaryAdmin", "Actions");

return Combine(icon, content, actions);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,7 @@ public override Task<IDisplayResult> DisplayAsync(User user, BuildDisplayContext
return CombineAsync(
Initialize<SummaryAdminUserViewModel>("UserFields", model => model.User = user).Location("SummaryAdmin", "Header:1"),
Initialize<SummaryAdminUserViewModel>("UserInfo", model => model.User = user).Location("DetailAdmin", "Content:5"),
Initialize<SummaryAdminUserViewModel>("UserButtons", model => model.User = user).Location("SummaryAdmin", "Actions:1"),
Initialize<SummaryAdminUserViewModel>("UserActionsMenu", model => model.User = user).Location("SummaryAdmin", "ActionsMenu:5")
Initialize<SummaryAdminUserViewModel>("UserButtons", model => model.User = user).Location("SummaryAdmin", "Actions:1")
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ internal static async Task<string> SendEmailConfirmationTokenAsync(this Controll
},
protocol: controller.HttpContext.Request.Scheme);

await SendEmailAsync(controller, user.Email, subject, new ConfirmEmailViewModel
await SendEmailAsync(controller, user.Email, subject, new ConfirmEmailViewModel()
{
User = user,
ConfirmEmailUrl = callbackUrl,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
Expand Down Expand Up @@ -31,7 +32,56 @@ public TwoFactorAuthenticationAuthorizationFilter(
_userManager = userManager;
_twoFactorHandlerCoordinator = twoFactorHandlerCoordinator;
}
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
ArgumentNullException.ThrowIfNull(context);

if (context.HttpContext?.User?.Identity?.IsAuthenticated == false ||
context.HttpContext.Request.Path.Equals("/" + _userOptions.LogoffPath, StringComparison.OrdinalIgnoreCase) ||
context.HttpContext.Request.Path.Equals("/" + _userOptions.TwoFactorAuthenticationPath, StringComparison.OrdinalIgnoreCase) ||
context.HttpContext.Request.Path.Equals("/TwoFactor-Authenticator/", StringComparison.OrdinalIgnoreCase))
{
await next();
return;
}

var routeValues = context.HttpContext.Request.RouteValues;
var areaName = routeValues["area"]?.ToString();

if (areaName != null && string.Equals(areaName, UserConstants.Features.Users, StringComparison.OrdinalIgnoreCase))
{
var controllerName = routeValues["controller"]?.ToString();

if (controllerName != null && _allowedControllerNames.Contains(controllerName, StringComparer.OrdinalIgnoreCase))
{
await next();
return;
}
}

if (context.HttpContext.User.HasClaim(claim => claim.Type == UserConstants.TwoFactorAuthenticationClaimType))
{
var user = await _userManager.GetUserAsync(context.HttpContext.User);

if (user == null)
{
await next();
return;
}

if (await _twoFactorHandlerCoordinator.IsRequiredAsync(user))
{
// 获取当前请求的 URL
var originalUrl = context.HttpContext.Request.GetEncodedUrl();
// 构建带有 returnUrl 参数的重定向 URL
var redirectUrl = $"/{_userOptions.TwoFactorAuthenticationPath}?returnUrl={Uri.EscapeDataString(originalUrl)}";
context.Result = new RedirectResult(redirectUrl);
return;
}
}

await next();
}
public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
{
ArgumentNullException.ThrowIfNull(context);
Expand Down Expand Up @@ -68,7 +118,26 @@ public async Task OnAuthorizationAsync(AuthorizationFilterContext context)

if (await _twoFactorHandlerCoordinator.IsRequiredAsync(user))
{
context.Result = new RedirectResult("~/" + _userOptions.TwoFactorAuthenticationPath);
// 获取当前访问的URL
var currentUrl = context.HttpContext.Request.GetEncodedUrl();
var requestScheme = context.HttpContext.Request.Scheme;
var host = context.HttpContext.Request.Host;
// var currentUrl = $"{requestScheme}://{host}{context.HttpContext.Request.PathBase}{context.HttpContext.Request.Path}{context.HttpContext.Request.QueryString}";

// var returnUrl = currentUrl.StartsWith($"{requestScheme}://{host}")
// ? $"{context.HttpContext.Request.PathBase}{context.HttpContext.Request.Path}{context.HttpContext.Request.QueryString}"
// : currentUrl;
// 如果是同域名,只保留路径部分
var returnUrl = currentUrl.StartsWith($"{requestScheme}://{host}")
? $"{context.HttpContext.Request.Path}{context.HttpContext.Request.QueryString}"
: currentUrl;

// 生成重定向URL
var redirectUrl = $"/{_userOptions.TwoFactorAuthenticationPath}?returnUrl={Uri.EscapeDataString(returnUrl)}";

context.Result = new RedirectResult(redirectUrl);

// context.Result = new RedirectResult("~/" + _userOptions.TwoFactorAuthenticationPath);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
using Fluid.Values;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using OrchardCore.Liquid;
using OrchardCore.Security;
using OrchardCore.Security.Permissions;
Expand Down Expand Up @@ -47,10 +46,6 @@ public static ValueTask<FluidValue> HasClaim(FluidValue input, FilterArguments a
if (string.Equals(claimType, Permission.ClaimType, StringComparison.OrdinalIgnoreCase) &&
user.HasClaim(StandardClaims.SiteOwner.Type, StandardClaims.SiteOwner.Value))
{
var logger = context.Services.GetRequiredService<ILogger<Startup>>();

logger.LogWarning("The tenant is using the 'has_claim' Liquid filter for Permission claims '{ClaimName}', which will break in the next major release of OrchardCore; please use 'has_permission: \"{ClaimName}\"' instead.", claimName, claimName);

return BooleanValue.True;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ public class TwoFactorMethod
public string Provider { get; set; }

public bool IsEnabled { get; set; }
public string ReturnUrl { get; set; }
}
1 change: 0 additions & 1 deletion src/OrchardCore.Modules/OrchardCore.Users/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,6 @@ public override void ConfigureServices(IServiceCollection services)
o.MemberAccessStrategy.Register<ConfirmEmailViewModel>();
});

services.AddScoped<IDisplayDriver<User>, UserRegistrationAdminDisplayDriver>();
services.AddSiteDisplayDriver<RegistrationSettingsDisplayDriver>();
services.AddNavigationProvider<RegistrationAdminMenu>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
using OrchardCore.DisplayManagement.Handlers;
using OrchardCore.Modules;
using OrchardCore.Mvc.Core.Utilities;
using OrchardCore.Security.Permissions;
using OrchardCore.Users.Controllers;
using OrchardCore.Users.Drivers;
using OrchardCore.Users.Endpoints.EmailAuthenticator;
Expand All @@ -33,12 +32,10 @@ public override void ConfigureServices(IServiceCollection services)
options.Filters.Add<TwoFactorAuthenticationAuthorizationFilter>();
});

services.AddScoped<IDisplayDriver<User>, UserTwoFactorDisplayDriver>();
services.AddScoped<IUserClaimsProvider, TwoFactorAuthenticationClaimsProvider>();
services.AddScoped<IDisplayDriver<UserMenu>, TwoFactorUserMenuDisplayDriver>();
services.AddSiteDisplayDriver<TwoFactorLoginSettingsDisplayDriver>();
services.AddScoped<IDisplayDriver<TwoFactorMethod>, TwoFactorMethodDisplayDriver>();
services.AddPermissionProvider<TwoFactorPermissionProvider>();
}

public override void Configure(IApplicationBuilder app, IEndpointRouteBuilder routes, IServiceProvider serviceProvider)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ public class EnableSmsAuthenticatorViewModel
public string Code { get; set; }

public string PhoneNumber { get; set; }
public string ReturnUrl { get; set; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ public class RequestCodeSmsAuthenticatorViewModel

[BindNever]
public bool AllowChangingPhoneNumber { get; set; }
public string ReturnUrl { get; set; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@

@if (Model.IsEnabled)
{
<a asp-action="Index" asp-controller="AuthenticatorApp" class="btn btn-sm btn-primary me-1">@T["Set"]</a>
<a asp-action="Index" asp-controller="AuthenticatorApp" asp-route-returnurl="@Model.ReturnUrl" class="btn btn-sm btn-primary me-1">@T["Set"]</a>
<a asp-action="Reset" asp-controller="AuthenticatorApp" class="btn btn-sm btn-danger">@T["Reset"]</a>
}
else
{
<a asp-action="Index" asp-controller="AuthenticatorApp" class="btn btn-sm btn-success">@T["Add"]</a>
<a asp-action="Index" asp-controller="AuthenticatorApp" asp-route-returnurl="@Model.ReturnUrl" class="btn btn-sm btn-success">@T["Add"]</a>
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,13 @@

<div asp-validation-summary="ModelOnly" class="text-danger" role="alert"></div>

<form method="post">
<form method="post" >
<div class="form-floating mb-3">
<input type="hidden" asp-for="PhoneNumber" />
<input asp-for="Code" class="form-control" autocomplete="off" placeholder="@T["Please enter the code"]" />
<label asp-for="Code" class="form-label form-label">@T["Verification code"]</label>
<span asp-validation-for="Code" class="text-danger"></span>
</div>
<input type="hidden" name="ReturnUrl" value="@ViewData["ReturnUrl"]" />
<button type="submit" class="btn btn-lg btn-primary">@T["Verify"]</button>
</form>
Loading