gpt4 book ai didi

CXF WS,拦截器 : stop processing, 响应错误

转载 作者:行者123 更新时间:2023-12-04 15:26:02 38 4
gpt4 key购买 nike

我正在挠头:
使用拦截器检查一些 SOAP header ,如何中止拦截器链但仍然向用户响应错误?

抛出错误对输出有效,但请求仍在处理中,我宁愿不让所有服务检查消息上下文中的某些标志。

使用“message.getInterceptorChain().abort();”中止真的会中止所有处理,但是也没有任何东西返回给客户端。

正确的做法是什么?

public class HeadersInterceptor extends AbstractSoapInterceptor {

public HeadersInterceptor() {
super(Phase.PRE_LOGICAL);
}

@Override
public void handleMessage(SoapMessage message) throws Fault {
Exchange exchange = message.getExchange();
BindingOperationInfo bop = exchange.getBindingOperationInfo();
Method action = ((MethodDispatcher) exchange.get(Service.class)
.get(MethodDispatcher.class.getName())).getMethod(bop);

if (action.isAnnotationPresent(NeedsHeaders.class)
&& !headersPresent(message)) {
Fault fault = new Fault(new Exception("No headers Exception"));
fault.setFaultCode(new QName("Client"));

try {
Document doc = DocumentBuilderFactory.newInstance()
.newDocumentBuilder().newDocument();
Element detail = doc.createElementNS(Soap12.SOAP_NAMESPACE, "mynamespace");
detail.setTextContent("Missing some headers...blah");
fault.setDetail(detail);

} catch (ParserConfigurationException e) {
}

// bad: message.getInterceptorChain().abort();
throw fault;
}
}
}

最佳答案

遵循 Donal Fellows 的建议我正在为我的问题添加一个答案。

CXF 严重依赖 Spring 的 AOP,这会导致各种问题,至少在这里是这样。我为您提供完整的代码。使用开源项目 我认为为可能决定不使用 WS-Security 的任何人提供我自己的几行代码是公平的(我希望我的服务仅在 SSL 上运行)。我通过浏览 CXF 源编写了其中的大部分内容。

如果您认为有更好的方法,请发表评论。

/**
* Checks the requested action for AuthenticationRequired annotation and tries
* to login using SOAP headers username/password.
*
* @author Alexander Hofbauer
*/
public class AuthInterceptor extends AbstractSoapInterceptor {
public static final String KEY_USER = "UserAuth";

@Resource
UserService userService;

public AuthInterceptor() {
// process after unmarshalling, so that method and header info are there
super(Phase.PRE_LOGICAL);
}

@Override
public void handleMessage(SoapMessage message) throws Fault {
Logger.getLogger(AuthInterceptor.class).trace("Intercepting service call");

Exchange exchange = message.getExchange();
BindingOperationInfo bop = exchange.getBindingOperationInfo();
Method action = ((MethodDispatcher) exchange.get(Service.class)
.get(MethodDispatcher.class.getName())).getMethod(bop);

if (action.isAnnotationPresent(AuthenticationRequired.class)
&& !authenticate(message)) {
Fault fault = new Fault(new Exception("Authentication failed"));
fault.setFaultCode(new QName("Client"));

try {
Document doc = DocumentBuilderFactory.newInstance()
.newDocumentBuilder().newDocument();
Element detail = doc.createElementNS(Soap12.SOAP_NAMESPACE, "test");
detail.setTextContent("Failed to authenticate.\n" +
"Please make sure to send correct SOAP headers username and password");
fault.setDetail(detail);

} catch (ParserConfigurationException e) {
}

throw fault;
}
}

private boolean authenticate(SoapMessage msg) {
Element usernameNode = null;
Element passwordNode = null;

for (Header header : msg.getHeaders()) {
if (header.getName().getLocalPart().equals("username")) {
usernameNode = (Element) header.getObject();
} else if (header.getName().getLocalPart().equals("password")) {
passwordNode = (Element) header.getObject();
}
}

if (usernameNode == null || passwordNode == null) {
return false;
}
String username = usernameNode.getChildNodes().item(0).getNodeValue();
String password = passwordNode.getChildNodes().item(0).getNodeValue();

User user = null;
try {
user = userService.loginUser(username, password);
} catch (BusinessException e) {
return false;
}
if (user == null) {
return false;
}

msg.put(KEY_USER, user);
return true;
}
}

如上所述,这里是 ExceptionHandler/-Logger。起初我无法将它与 JAX-RS 结合使用(也通过 CXF,JAX-WS 现在工作正常)。反正我不需要 JAX-RS,所以这个问题现在已经消失了。

@Aspect
public class ExceptionHandler {
@Resource
private Map<String, Boolean> registeredExceptions;


/**
* Everything in my project.
*/
@Pointcut("within(org.myproject..*)")
void inScope() {
}

/**
* Every single method.
*/
@Pointcut("execution(* *(..))")
void anyOperation() {
}

/**
* Log every Throwable.
*
* @param t
*/
@AfterThrowing(pointcut = "inScope() && anyOperation()", throwing = "t")
public void afterThrowing(Throwable t) {
StackTraceElement[] trace = t.getStackTrace();
Logger logger = Logger.getLogger(ExceptionHandler.class);

String info;
if (trace.length > 0) {
info = trace[0].getClassName() + ":" + trace[0].getLineNumber()
+ " threw " + t.getClass().getName();
} else {
info = "Caught throwable with empty stack trace";
}
logger.warn(info + "\n" + t.getMessage());
logger.debug("Stacktrace", t);
}

/**
* Handles all exceptions according to config file.
* Unknown exceptions are always thrown, registered exceptions only if they
* are set to true in config file.
*
* @param pjp
* @throws Throwable
*/
@Around("inScope() && anyOperation()")
public Object handleThrowing(ProceedingJoinPoint pjp) throws Throwable {
try {
Object ret = pjp.proceed();
return ret;
} catch (Throwable t) {
// We don't care about unchecked Exceptions
if (!(t instanceof Exception)) {
return null;
}

Boolean throwIt = registeredExceptions.get(t.getClass().getName());
if (throwIt == null || throwIt) {
throw t;
}
}
return null;
}
}

关于CXF WS,拦截器 : stop processing, 响应错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8316354/

38 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com