我正在接受关于如何处理问题编码的一些指导,我不想直接编写代码而不考虑它,因为我需要它尽可能通用和可定制,
该场景是我有一个Web服务,充当下游服务的网关,目的是验证和授权下游服务的SOAP消息,基本上是将下游服务自行完成。每个SOAP消息都有各种不同的WS-Security机制,通常是WS-UsernameToken,WS-Timestamp和消息体的XML签名。
我的问题是我想要找出一种很好的可扩展的方法来验证所有这些安全机制,我不是在如何做到如何评估它。
我想过有一个初始化的控制器类并控制验证流程,即
ISecurityController controller = SecurityControllerFacotry.getInstance();
boolean proceed = controller.Validate(soapMessage);
使用它非常像模板设计模式,它颠覆了逻辑的流程,即
public Boolean Validate(Message soapMessage)
{
return ValidateAuthentication(soapMessage) && ValidateTimeStamp(soapMessage) && ValidateSignture(soapMessage);
}
这会成为解决问题的最佳方法吗?
最好将这些验证方法分别放在一个实现了通用接口的类中吗?这样一个类就可以从某种验证工厂中实例化和检索,即
IValidationMechanism val = ValidationFactory.getValidationType(ValidationFactory.UsernameToken);
boolean result = val.Validate(soapMessage);
这将为我提供一个易于扩展的方面。
这是一个有效的解决方案还是任何人都可以想到其他方法呢?
我喜欢设计模式和良好的原则,所以如果可能的话,我想沿着这条路走下去。
提前致谢
乔恩
编辑:该服务基本上是一种网关安全服务,可以减轻身后服务的身份验证和授权负担。安全服务可以被认为是SOAP消息路径上的隐式调用中介,它验证SOAP消息中的安全机制,并且根据验证结果,通过询问WS-addressing头来将消息转发到适当的下游服务。虽然服务不是真正的问题,但更多的是关于如何实施验证程序。
答案 0 :(得分:2)
我认为你对此的直觉是好的;采用单一界面方法。也就是说,将验证实现隐藏在单个验证接口之后;这允许您稍后扩展验证实现,而无需修改调用代码。
是的,将验证放入自己的类中的想法很好;你可能想要考虑拥有一个公共基类,如果你有任何常见的验证项(例如,用户名可能是一个常见的验证元素,即使每个不同的验证方案可能以不同的方式编码;一个作为元素,另一个作为一个元素属性等)。我认为验证类是一种更适合你所讨论的复杂程度的映射,而不是验证方法;我怀疑你正在进行的验证类型需要一组方法(即类)。
答案 1 :(得分:1)
我可以想到另一种根据不同的验证来验证SOAP消息的方法。您使用访客模式。
为此,您将获得一个围绕SOAP消息的简单包装器。
MySoapMessage{
SOAPMessage soapMessage;
List<String> validatonErrors;
void accept(Validator validator){
validator.isValid(this);
}
}
您的安全控制器将包含您将基本注入的Validatiors列表。
SecurityController{
List<IValidator> validators;
//Validate the message
void validate(MySOAPMessage soapMessage){
forEach(Validator validator: validators){
soapMessage.isValid(validator)
}
}
}
你的验证器看起来像这样。
UserNameValidator implements IValidator{
public void validate(MySOAPMessage message){
// Validate and put error if any
}
}
你不需要和不必要的工厂这里的验证器..如果你想要从控制器添加/删除验证器,你只需从列表中注入/取消注入。
答案 2 :(得分:1)
Spring有一个通用的验证包,可以很好地处理这种类型的进程恕我直言。
他们看起来像
public interface Validator {
public boolean supports(Class<?> clazz);
public void validate(Object o, Errors errors);
}
当然,他们正在使用Errors
参数来返回验证问题,这可能会或可能不符合您的目标。