(ServiceStack)基于消息的体系结构中业务逻辑的位置

时间:2016-10-20 10:25:36

标签: security servicestack

在基于消息的设计中放置业务逻辑的最佳做法是什么?

我正在使用servicestack构建我的api。

The wiki显示了在邮件上放置RequiredRole属性而不是处理邮件的服务的示例。

从某种意义上说,[RequiredRole] / [Authenticate]是附加到邮件的业务逻辑/安全性。

具体示例

比如说我会添加DeleteAddress消息:

public class DeleteAddress : IReturn<bool>
{
    public int AddressId { get; set; }
}

但为了确保安全,我想检查管理员角色,ManageAllAddresses的权限或者AddressId是否链接到此用户(可能是在会话中,可能是通过数据库调用)。

我最好怎么做?

命题

以下代码是否是良好做法,如果是,我将如何实施?

[RequiredRole("Admin")]
[RequiredPermission("ManageAllAddresses ")]
[RequiredAddressLinkedToAccount]
public class DeleteAddress : IReturn<bool>
{
    public int AddressId { get; set; }
}

2 个答案:

答案 0 :(得分:1)

ServiceStack's recommendation is to keep your ServiceModel free of dependencies so we'd recommend to annotate your Service implementation classes instead which you can annotate either on the Service class to apply to all Operations or on the individual methods to apply just to that operation, e.g:

[RequiredRole("Admin")]
public class AddressServices : Service
{
    [RequiredPermission("ManageAllAddresses ")]
    [RequiredAddressLinkedToAccount]
    public object Any(DeleteAddress request)
    {
    }
}

Please note ServiceStack requires your Services to return reference types, which is typically a Response DTO but can also be a string, e.g:

public class DeleteAddress : IReturn<string>
{
    public int AddressId { get; set; }
}

答案 1 :(得分:0)

To finish of this question. I could make a request filter and add it on the service.

Either inherit from AuthenticateAttribute or Directly from RequestFilterAttribute.

public class RequiredAddressLinkedToAccount : AuthenticateAttribute
{
    public RequiredRoleAttribute(ApplyTo applyTo)
    {
        this.ApplyTo = applyTo;
        this.Priority = (int)RequestFilterPriority.RequiredRole;
    }



    public override void Execute(IRequest req, IResponse res, object requestDto)
    {
        var dto = requestDto as ILinkedToAccount;
        var session = req.GetSession();
        if(dto.AccountId == session.Id)
            return; //we dont want anything to be blocked if the account Id is there.

        //Implement like RequireRoleAttribute
        if (DoHtmlRedirectIfConfigured(req, res)) 
            return;

        res.StatusCode = (int)HttpStatusCode.Forbidden;
        res.StatusDescription = "Address does not belong to you";
        res.EndRequest();

    }
}