静态地我设置了对我的服务的访问权限:
[Authenticate]
public class AppUserService : Service
{
[RequiredRole("Administrator")]
public object Post(CreateAppUser request)
{
//.....
}
}
如何以编程方式执行此操作?
我将让用户使用GUI创建角色。然后我将列出可用的方法,例如通过提供使用改进代码的方法,如:
var appHost = HostContext.AppHost;
var restPaths = appHost.RestPaths;
foreach (var restPath in restPaths)
{
var reqType = restPath.RequestType;
string verbs = string.Empty;
if (restPath.Verbs != null)
{
var counter = 0;
foreach (var verb in restPath.Verbs)
{
if (counter > 0) verbs += ", ";
verbs += verb;
counter++;
}
}
Debug.WriteLine($"Path: {restPath.Path} | Verbs: {verbs} | Name: {reqType.Name} FullName: {reqType.FullName}");
}
上面的代码输出类似
的内容Path: /appusers | Verbs: POST | Name: CreateAppUser FullName: MyServer.ServiceModel.DTOs.Request.CreateAppUser
所以我可以在我的UI中显示Name
的{{1}}属性,让他定义允许哪些角色调用此方法。因此,用户可以创建一个名为“用户管理”的角色。并允许此角色的成员执行RequestType
。
使用注释我会写
CreateAppUser
这在C#代码中是否可行?
答案 0 :(得分:2)
ServiceStack确实有一种在运行时动态添加属性的方法,例如:
typeof(CreateAppUser)
.AddAttributes(new RequiredRoleAttribute("Administrator", "User Management"));
这是静态声明属性的替代方法,但它仍然不是数据驱动授权系统的解决方案。
但您可以通过在服务中验证ServiceStack的内置属性来添加自己的自定义授权逻辑:
public ICustomAuth CustomAuth { get; set; }
public object Post(CreateAppUser request)
{
var session = base.GetSession();
var requiresRoles = CustomAuth.GetRequiredRoles(request.GetType());
var hasAllRoles = requiresRoles.All(r =>
session.HasRole(r, base.AuthRepository))
if (!hasAllRoles)
throw new UnauthorizedAccessException("Requires all roles");
}
如果你这么做很多,你会想要将自定义验证逻辑重构为一个可重复使用的方法,或者如果你喜欢自定义RequestFilter属性。