Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Design patterns Restlet:使用SecretVerifier和Enroler类强制对数据库进行两次往返。这种模式有效吗?_Design Patterns_Restlet - Fatal编程技术网

Design patterns Restlet:使用SecretVerifier和Enroler类强制对数据库进行两次往返。这种模式有效吗?

Design patterns Restlet:使用SecretVerifier和Enroler类强制对数据库进行两次往返。这种模式有效吗?,design-patterns,restlet,Design Patterns,Restlet,在Restlet中,您有一个名为SecretVerifier的类,它具有一个抽象方法verify(字符串标识符,char[]secret),您要在子类中重写该方法。基类还将创建一个用标识符初始化的User对象。到目前为止还不错 现在需要实现Enroler接口,以便将角色“添加”到前面提到的User对象(通过ClientInfo对象传递给子类)。这里是向用户对象“添加”角色的地方 让我们假设ChallengeAuthenticator正在用于身份验证 问题:这两个类都非常不同,您没有访问相应请求/

在Restlet中,您有一个名为
SecretVerifier
的类,它具有一个抽象方法
verify(字符串标识符,char[]secret)
,您要在子类中重写该方法。基类还将创建一个用标识符初始化的
User
对象。到目前为止还不错

现在需要实现
Enroler
接口,以便将角色“添加”到前面提到的
User
对象(通过
ClientInfo
对象传递给子类)。这里是向用户对象“添加”角色的地方

让我们假设
ChallengeAuthenticator
正在用于身份验证

问题:这两个类都非常不同,您没有访问相应请求/响应对象的权限。这种设计迫使您执行两次到DB的往返-一次验证密码,另一次获取用户角色。这是一个有效的设计吗

可以说,您可以在一个查询中获取所有内容。由于这两个类将分别调用相应的DAO,因此将有2个对DB的调用


当然,您可以通过重写
SecretVerifier.getIdentifier(Request-req,resp)
使代码稍微复杂一些,然后使用它获取所有内容并添加角色-但是
verify
方法似乎是
模板
模式的一部分,您无法真正控制基类中发生的事情,除非您直接实现
Verifier
,重新发明轮子,并稍微“调整”代码……但问题在于设计决策。我不想开始辩论。我只想知道这样的东西(两次)一次用于身份验证,另一次用于角色,非常常见,在中高负载下是有效的?

我很理解你的问题。事实上,身份验证和授权是两个截然不同的问题。在您的情况下,您可以在应用程序中处理这两个问题,但当您通过OpenID使用外部身份验证提供程序时,情况并不总是如此。在这种情况下,选择的提供者进行身份验证,然后您管理当前用户的角色

关于您的问题,您可以在对数据库的一次调用中执行身份验证和授权处理。您需要在验证器实体中获取用户/角色提示,然后使用当前请求实例将其传递给enroler实体

以下是一个例子:

  • 验证人:

    public class MySecretVerifier extends SecretVerifier {
        private SecurityDao securityDao = (...);
    
        public int verify(String identifier, char[] secret)
                             throws IllegalArgumentException {
            ApplicationUser user = securityDao.loadUser(identifier);
            //user contains both user hints and roles
            if (user!=null
                  && compare(user.getPassword().toCharArray(), secret)) {
                Request request = Request.getCurrent();
                request.getAttributes().put("currentUser", user);
                return SecretVerifier.RESULT_VALID;
            } else {
                return SecretVerifier.RESULT_INVALID;
            }
        }
    }
    
  • 登记者:

    public class MyEnroler implements Enroler {
        public void enrole(ClientInfo clientInfo) {
            Request request = Request.getCurrent();
            User user = request.getAttributes().put("currentUser");
            if (user!=null) {
                List<UserRole> roles = user.getRoles();
                if (roles!=null) {
                    for (UserRole userRole : roles) {
                        // example of role creation
                        Role role = new Role(userRole.getName(), "");
                        clientInfo.getRoles().add(role);
                    }
                }
            }
        }
    }
    
    公共类MyEnroler实现Enroler{
    public void enrole(ClientInfo ClientInfo){
    Request=Request.getCurrent();
    User User=request.getAttributes().put(“当前用户”);
    如果(用户!=null){
    List roles=user.getRoles();
    if(角色!=null){
    for(用户角色用户角色:角色){
    //角色创建示例
    Role Role=新角色(userRole.getName(),“”);
    clientInfo.getRoles().add(角色);
    }
    }
    }
    }
    }
    
希望对你有帮助。
Thierry

你不会相信我真的想到了这种方法,但不知道从设计的角度来看,采用这种方法是否“合适”—而且似乎还可以!!!使用请求获取用户的注册器中的行已指定“put”,这应该是“get”正确吗?我知道这是一个很老的帖子,但我猜和我一样,很多人在使用Restlet时仍然会找到它searches@ars265如果他们这样做了,那么他们将非常节俭地使用他们的选票。