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