2016-10-28 63 views
3

静态我将像这样进入我的服务:如何以编程方式分配角色和权限,以服务和/或RequestDTOs

[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显示RequestTypeName财产,让他定义是什么,角色允许调用这个方法。因此,用户可以创建一个名为“用户管理”的角色,并允许该角色的成员执行CreateAppUser

使用注释我会写

[RequiredRole("Administrator", "User Management")] 
public object Post(CreateAppUser request) 
{ .... } 

这是无论如何可能在C#代码?

回答

2

ServiceStack确实有办法在运行时动态添加属性,e.g:

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属性。

+0

谢谢德米斯,我认为自定义的RequestFilter是最好的方法。我会稍后再试。 – ThommyB