我正在使用ASP.NET Core 3.0和Razor Pages开发一个Web应用程序。我要添加一个功能,该功能允许用户按页面名称进行搜索-假设用户搜索“密码”,结果为“更改密码”,即剃刀页面。
我想页面模型看起来像这样:
[SearchablePage(Name="Manage Account", Keywords="password,username,change")]
public class ManageAccountModel : PageModel
{
...
}
到目前为止,我通过注入IActionDescriptorCollectionProvider
并寻找PageActionDescriptor
项来设法进行页面发现。这将向我显示该应用程序中的所有页面。
我不确定如何进入每个页面的实际PageModel
类,以便确定自定义搜索属性的值。
我还试图弄清是否已授权用户以查看页面-无论是来自授权属性还是Startup.cs中配置的授权约定。
任何帮助或指针在哪里寻找,将不胜感激!
谢谢!
更新
我设法找到了框架documentation提供的IAuthorizationService
。现在的诀窍是检索剃刀页面的所有策略。
答案 0 :(得分:0)
我有以下页面列出了我的Web应用程序中的所有路由。我用来诊断端点。用作起点可能会很有用。我不确定您将如何获得授权信息。
public class RoutesModel : PageModel {
private readonly IActionDescriptorCollectionProvider _actionDescriptorCollectionProvider;
public RoutesModel(IActionDescriptorCollectionProvider actionDescriptorCollectionProvider) {
this._actionDescriptorCollectionProvider = actionDescriptorCollectionProvider;
}
public List<RouteInfo> Routes { get; set; }
public void OnGet() {
Routes = _actionDescriptorCollectionProvider.ActionDescriptors.Items
.Select(x => new RouteInfo {
Action = x.RouteValues["Action"],
Controller = x.RouteValues["Controller"],
Name = x.AttributeRouteInfo?.Name,
Template = x.AttributeRouteInfo?.Template,
Constraint = x.ActionConstraints == null ? "" : JsonConvert.SerializeObject(x.ActionConstraints)
})
.OrderBy(r => r.Template)
.ToList();
}
public class RouteInfo {
public string Template { get; set; }
public string Name { get; set; }
public string Controller { get; set; }
public string Action { get; set; }
public string Constraint { get; set; }
}
}
答案 1 :(得分:0)
我设法找到了一个可行的解决方案,目前已使用Pages(而非控制器和视图)对其进行了测试。
必需的界面
IActionDescriptorCollectionProvider
-提供所有Razor页面的列表。PageLoader
-加载Razor页面,解析其安全策略和类属性。IAuthorizationService
-确定用户是否有权使用策略。步骤
获取所有剃须刀页面的列表。
var pageDescriptors = _descriptorProvider.ActionDescriptors.Items
.OfType<PageActionDescriptor>()
.ToArray();
浏览页面并加载每个页面:
var compiledPage = await _pageLoader.LoadAsync(pageDescriptor);
这时,您可以根据添加到页面模型的属性进行一些处理。请注意,您添加到页面模型类的任何属性都将在EndpointMetadata
中自动解析,无需进行自定义反射工作!
var pageMetadata = compiledPage.EndpointMetadata
.OfType<PageMetadataAttribute>() // My custom attribute.
.FirstOrDefault();
请注意,策略和授权将以AuthorizeAttribute
实例的形式添加到Razor页面元数据中。
提取授权属性,遍历它们并进行评估。
var authorization = compiledPage.EndpointMetadata
.OfType<AuthorizeAttribute>()
.ToArray();
foreach (var auth in authorization)
{
if (!string.IsNullOrEmpty(auth.Policy))
{
var authResult = await _authorizationService.AuthorizeAsync(
_httpContextAccessor.HttpContext.User,
auth.Policy);
if (!authResult.Succeeded) return; // Do stuff here.
}