【问题标题】:Access Servicstack.net session in validator在验证器中访问 Servicstack.net 会话
【发布时间】:2013-12-15 13:08:20
【问题描述】:

如何在我的验证码中访问 ServiceStack.net 会话?

public class UserSettingsValidator : AbstractValidator<UserSettingsRequest>
{
    public UserSettingsValidator()
    {
        RuleFor(x => x.UserId)
            .SetValidator(new PositiveIntegerValidator())
            .SetValidator(new UserAccessValidator(session.UserId)); //<-- I need to pass the UserID from the session here
    }
}

在我刚刚做的服务实现中:

var session = base.SessionAs<UserSession>();

但这不适用于我的抽象验证器。

谢谢!

编辑:这是版本 3.9.71.0

【问题讨论】:

    标签: c# validation session servicestack servicestack-bsd


    【解决方案1】:

    我假设您只是使用ValidationFeature 插件,就像大多数人一样。如果是这样的话,那我认为这是不可能的。最终ValidationFeature 是一个使用RequestFilter 的插件。

    我以前也想做类似的事情,后来意识到这是不可能的。

    RequestFilterServiceRunner 之前运行。请参阅order of operations guide here

    这对您意味着您的填充请求 DTO 到达您的服务,并且验证功能的请求过滤器将在创建 ServiceRunner 之前尝试验证您的请求。

    ServiceRunner 是您的服务类实例处于活动状态的位置。您的服务类实例将被注入您的UserSession 对象。

    因此,此时您无法进行任何依赖于会话的验证。

    过于复杂?:

    可以在您的服务方法中进行验证,您可以创建一个自定义对象,允许您将会话与要验证的对象一起传递。 (见下一节)。但我会问自己,你是否过于复杂了你的验证?

    为了简单检查请求UserId匹配会话的UserId,大概你这样做是为了让用户只能对自己的记录进行更改;为什么不检查服务的操作方法并抛出Exception?我猜人们不应该更改此 ID,因此这与其说是验证问题,不如说是安全异常。 但就像我说的,也许你的情况不同。

    public class SomeService : Service
    {
        public object Post(UserSettingsRequest request) // Match to your own request
        {
            if(request.UserId != Session.UserId)
                throw new Exception("Invalid UserId");
        }
    }
    

    服务操作中的验证:

    您应该阅读using Fluent Validators。您可以在自己的服务方法中调用自定义验证器。

    // This class allows you to add pass in your session and your object
    public class WithSession<T>
    {
        public UserSession Session { get; set; }
        public T Object { get; set; }
    }
    
    public interface IUserAccessValidator
    {
        bool ValidUser(UserSession session);
    }
    
    public class UserAccessValidator : IUserAccessValidator
    {
        public bool ValidUser(UserSession session)
        {
            // Your validation logic here
            // session.UserId
            return true;
        }
    }
    
    public class UserSettingsValidator : AbstractValidator<WithSession<UserSettingsRequest>>
    {
        public IUserAccessValidator UserAccessValidator { get; set; }
    
        public UserSettingsValidator()
        {
            // Notice check now uses .Object to access the object within
            RuleFor(x => x.Object.UserId)
                .SetValidator(new PositiveIntegerValidator());
    
            // Custom User Access Validator check, passing the session
            RuleFor(x => x.Session).Must(x => UserAccessValidator.ValidUser(x)); 
        }
    }
    

    然后在您的服务中实际使用验证器:

    public class SomeService : Service
    {
        // Validator with be injected, you need to registered it in the IoC container.
        public IValidator<WithSession<UserSettingsRequest>> { get; set; }
    
        public object Post(UserSettingsRequest request) // Match to your own request
        {
            // Combine the request with the current session instance
            var requestWithSession = new WithSession<UserSettingsRequest> {
                Session = this.Session,
                Object = request
            };
    
            // Validate the request
            ValidationResult result = this.Validator.Validate(requestWithSession);
            if(!result.IsValid)
            {
                throw result.ToException();
            }
    
            // Request is valid
            // ... more logic here
            return result;
        }
    }
    

    我希望这会有所帮助。 注意:代码未经测试

    【讨论】:

    • 哇!感谢这个很好的解释!你是对的,这更像是一个安全问题,我将直接在服务操作中检查这一点。非常感谢!
    • @caribertl 很高兴它有帮助
    【解决方案2】:

    看来,在阅读了一群遇到类似问题的人之后,然后花了几个小时玩了几个基于 SS4 Cookbook 等的解决方案,这是一个已经解决的问题:

    https://forums.servicestack.net/t/blaz-miheljak-355-feb-3-2015/176/2

    在您的验证器上实现 IRequiresRequest 接口,瞧。

    【讨论】:

      猜你喜欢
      • 2013-06-22
      • 1970-01-01
      • 1970-01-01
      • 2014-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-09
      相关资源
      最近更新 更多