我首先要说的是我倾向于过度设计事物。我的环境是 Blazor 服务器端和 .Net 6。
我有 3 个用于授权的应用程序角色。角色分配在 Azure 应用程序服务中处理,并传递到清单中的我的应用程序。在登录过程中,我用
user.IsInRole(<role name>)
读出它们并将它们保存到ProtectedSessionStorage
。它们几乎用在每个组件中,以根据用户的角色启用/禁用功能。
我创建了一个基类,每个类都继承它,以管理基本访问,即
[Authorize(Roles = "Approver, Owner")]
。为了获取组件访问的角色,我开始从存储中检索它var isApprover = (await Storage.GetAsync<bool>("IsApprover")).Value;
我认为存储源应该是不可见的。换句话说,开发人员不必知道信息是否在会话存储、Redis 或其他任何地方。他们应该只能访问属性“IsApprover”、“IsOwner”等。这样就可以更改存储,并且您不必更新十几个不同的位置。
我正在尝试获取基类中的存储值。我尝试将其放入构造函数中
public BasePage()
{
IsApprover = Storage.GetAsync<bool>("IsApprover").Result.Value;
}
但是
ProtectedSessionStorage
已注入,因此尚不可用。
我尝试在
OnInitialized
中这样做
protected async override Task OnInitializedAsync()
{
IsApprover = (await Storage.GetAsync<bool>("IsApprover")).Value;
}
但我不能在每个子类中调用 OnInitialized,这也违背了我仅拥有该属性的目标。
我还尝试了基类中的属性
setter
private bool _ta { get; set; }
public bool IsTaxApprover {
get { return _ta; }
set {
_ta = Storage.GetAsync<bool>("IsTaxApprover").Result.Value;
}
}
但它似乎从未设置该值。我检查索引页面上继承 Base 的值
if (IsTaxApprover)
<do stuff here...>
else
<do stuff here...>
但该值从未设置。
感谢您提供的任何帮助。
感谢@MrC aka Shaun Curtis 为我指明了正确的方向。
我发现我可以创建一个带有公开属性的接口的服务。首先,我创建了两个属性。
public interface IAuthorizationService
{
bool IsApprover { get; }
bool IsOwner { get; }
}
然后在类中我从身份验证服务填充属性。
public class AuthorizationService : IAuthorizationService
{
private AuthenticationState AuthState { get; set; }
bool _isOwner;
bool IAuthorizationService.IsOwner {
get => _isOwner; }
bool _isApprover;
bool IAuthorizationService.IsApprover {
get => _isApprover; }
public AuthorizationService(AuthenticationStateProvider authState) {
AuthState = authState.GetAuthenticationStateAsync().Result;
var user = AuthState.User;
_isOwner = user.IsInRole("TaxonomyOwner");
_isApprover = user.IsInRole("TaxonomyApprover");
}
}
如果您使用 DI,则必须像任何其他服务一样在您的 Program.CS 中注册。然后我将其注入构造函数中,并且属性可用。例如,在我的索引页面中,我在
OnInitialization
中检查授权
if (AuthService.IsApprover == true)
result = await RequestDomain.GetAllRequestsAsync(ChangePeriod.ChangePeriodId).ConfigureAwait(false);
else
result = await RequestDomain.GetRequestsAsync(UserEmail ?? "").ConfigureAwait(false);