好的,我已经尝试了一个解决方案,它在一定程度上奏效了。这是详细信息;
使用以下 services.xml 创建了 TestService
<serviceGroup>
<service name="TestWebService" scope="application" targetNamespace="http://TestServiceWs">
<schema schemaNamespace="http://TestServiceWs"/>
<description>Test POJO Axis2 AAR deployment</description>
<parameter name="ServiceClass">test.TestServiceWS</parameter>
<messageReceivers>
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only"
class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"/>
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
</messageReceivers>
</service>
<module ref="rampart" />
<parameter name="InflowSecurity">
<action>
<items>UsernameToken Timestamp</items>
<passwordCallbackClass>test.PWHandlerServer</passwordCallbackClass>
</action>
</parameter>
</serviceGroup>
已实现PWHandlerServer.java
package test;
import java.io.IOException;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import org.apache.ws.security.WSPasswordCallback;
public class PWHandlerServer implements CallbackHandler {
// the username and password we expect incoming WS calls to use
private String user = "wsuser";
private String pwd = "wspwd";
public void handle (Callback[] callbacks) throws IOException, UnsupportedCallbackException {
for (int i = 0; i < callbacks.length; i++) {
if (callbacks[i] instanceof WSPasswordCallback) {
WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];
System.out.println("identifier: "+pc.getIdentifer()+", usage: "+pc.getUsage());
if (pc.getUsage() == WSPasswordCallback.USERNAME_TOKEN) {
// for passwords sent in digest mode we need to provide the password,
// because the original one can't be un-digested from the message
// we can throw either of the two Exception types if authentication fails
if (! user.equals(pc.getIdentifer()))
throw new IOException("unknown user: "+pc.getIdentifer());
// this will throw an exception if the passwords don't match
pc.setPassword(pwd);
} else if (pc.getUsage() == WSPasswordCallback.USERNAME_TOKEN_UNKNOWN) {
// for passwords sent in cleartext mode we can compare passwords directly
if (! user.equals(pc.getIdentifer()))
throw new IOException("unknown user: "+pc.getIdentifer());
// we can throw either of the two Exception types if authentication fails
if (! pwd.equals(pc.getPassword()))
throw new IOException("password incorrect for user: "+pc.getIdentifer());
}
// If everything is OK then set the context and move on
TestRequestContext ctx = new TestRequestContext(pc.getIdentifer());
TestRequestContext.setRequestContext(ctx);
} else {
throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback");
}
}
}
}
已实现TestRequestContext
package test;
class TestRequestContext {
private final static ThreadLocal<TestRequestContext> currentContext = new ThreadLocal<TestRequestContext>();
public static void setRequestContext(TestRequestContext context) {
currentContext.set(context);
}
public static TestRequestContext getRequestContext() {
return currentContext.get();
}
public static void clearRequestContext() {
currentContext.remove();
}
private String userPrincipal;
public TestRequestContext(String principal) {
this.userPrincipal = principal;
}
public String getUserPrincipal(){
return this.userPrincipal;
}
}
现在我应该能够在我的 Web 服务类中访问我的 TestRequestContext.getUserPricipal() 并将其传递给 DB 以进行事务和切换安全上下文。唯一的问题是当我尝试通过 SoapUI 访问服务时,它给了我以下异常;
15:07:34,924 INFO [STDOUT] identifier: wsuser, usage: 5
15:08:48,081 INFO [STDOUT] [ERROR] WSDoAllReceiver: security processing failed (actions mismatch)
org.apache.axis2.AxisFault: WSDoAllReceiver: security processing failed (actions mismatch)
at org.apache.rampart.handler.WSDoAllReceiver.processBasic(WSDoAllReceiver.java:344)
at org.apache.rampart.handler.WSDoAllReceiver.processMessage(WSDoAllReceiver.java:86)
at org.apache.rampart.handler.WSDoAllHandler.invoke(WSDoAllHandler.java:72)
at org.apache.axis2.engine.Phase.invoke(Phase.java:318)
at org.apache.axis2.engine.AxisEngine.invoke(AxisEngine.java:254)
at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:160)
at org.apache.axis2.transport.http.HTTPTransportUtils.processHTTPPostRequest(HTTPTransportUtils.java:173)
at org.apache.axis2.transport.http.AxisServlet.doPost(AxisServlet.java:144)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:710)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:182)
at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:157)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:262)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:446)
at java.lang.Thread.run(Thread.java:619)
在 SoapUI 中,我只是使用“身份验证”选项卡来设置用户名和密码并调用?我需要在调用之前设置其他任何东西吗?
另外,使用 ThreadLocal 的方法是正确的,还是我也可以通过其他方式访问该原理?
谢谢。