当前位置: 首页 > 知识库问答 >
问题:

WSSecurityException-处理标头时发现错误

叶谦
2023-03-14

我构建了一个基于CXF的soap web服务,并试图按照本教程的步骤使用WS-Security添加一些安全方面。

我得到一个错误被发现处理头

以下是将安全方面添加到soap ws的重要类

ServerPasswordCallback.java

    import java.io.IOException;
    import java.util.ResourceBundle;
    import javax.security.auth.callback.Callback;
    import javax.security.auth.callback.CallbackHandler;
    import javax.security.auth.callback.UnsupportedCallbackException;
    import org.apache.wss4j.common.ext.WSPasswordCallback;

    public class ServerPasswordCallback implements CallbackHandler {
        private static final String BUNDLE_LOCATION = "auth";
        private static final String PASSWORD_PROPERTY_NAME = "auth.manager.password";

        private static String password;

        static {
            final ResourceBundle bundle = ResourceBundle.getBundle(BUNDLE_LOCATION);
            password = bundle.getString(PASSWORD_PROPERTY_NAME);
        }

        @Override
        public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
            WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
            pc.setPassword(password);
        }
    }

ClientPasswordCallback.java

    import java.io.IOException;
    import java.util.ResourceBundle;
    import javax.security.auth.callback.Callback;
    import javax.security.auth.callback.CallbackHandler;
    import javax.security.auth.callback.UnsupportedCallbackException;
    import org.apache.wss4j.common.ext.WSPasswordCallback;


    public class ClientPasswordCallback implements CallbackHandler {

        private static final String BUNDLE_LOCATION = "auth";
        private static final String PASSWORD_PROPERTY_NAME = "auth.manager.password";
        private static String password;

        static {
            final ResourceBundle bundle = ResourceBundle.getBundle(BUNDLE_LOCATION);
            password = bundle.getString(PASSWORD_PROPERTY_NAME);
        }

        @Override
        public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
            WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
            pc.setPassword(password);
        }
    }

authServiceFactory.java

    public final class AuthServiceFactory {

        private static final ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {
                    "com/company/auth/service/cxfClient.xml"
                });

        public AuthServiceFactory() {
        }

        public AuthService getService() {
            return (AuthService) context.getBean("client");
        }
    }

auth_fr_fr

auth.manager.password=*****

CxfClient.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws"
        xmlns:jaxrs="http://cxf.apache.org/jaxrs"
        xsi:schemaLocation="http://cxf.apache.org/jaxws 
                            http://cxf.apache.org/schemas/jaxws.xsd
                            http://www.springframework.org/schema/beans 
                            http://www.springframework.org/schema/beans/spring-beans.xsd
                            http://cxf.apache.org/jaxrs 
                            http://cxf.apache.org/schemas/jaxrs.xsd">

        <bean id="proxyFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
            <property name="serviceClass" value="com.company.auth.service.AuthService" />
            <property name="address"
                value="http://localhost:8080/CXFSOAP-WebService/corporateAuth" />
            <property name="inInterceptors">
                <list>
                    <ref bean="logIn" />
                </list>
            </property>
            <property name="outInterceptors">
                <list>
                    <ref bean="logOut" />
                    <ref bean="saajOut" />
                    <ref bean="wss4jOut" />
                </list>
            </property>
        </bean>

        <bean id="client" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean"
            factory-bean="proxyFactory" factory-method="create" />

        <bean id="logIn" class="org.apache.cxf.interceptor.LoggingInInterceptor" />
        <bean id="logOut" class="org.apache.cxf.interceptor.LoggingOutInterceptor" />
        <bean id="saajOut" class="org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor" />
        <bean id="wss4jOut" class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
            <constructor-arg>
                <map>
                    <entry key="action" value="UsernameToken" />
                    <entry key="user" value="ws-client" />
                    <entry key="passwordType" value="PasswordText" />
                    <entry key="passwordCallbackClass" value="com.company.auth.service.ClientPasswordCallback" />
                </map>
            </constructor-arg>
        </bean>
    </beans>

此文件用于客户端配置

beans.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws"
        xmlns:jaxrs="http://cxf.apache.org/jaxrs"
        xsi:schemaLocation="http://cxf.apache.org/jaxws 
                            http://cxf.apache.org/schemas/jaxws.xsd
                            http://www.springframework.org/schema/beans 
                            http://www.springframework.org/schema/beans/spring-beans.xsd
                            http://cxf.apache.org/jaxrs 
                            http://cxf.apache.org/schemas/jaxrs.xsd">

        <jaxws:endpoint id="bookShelfService"
            implementor="com.company.auth.service.AuthServiceImpl" address="/corporateAuth">
            <jaxws:inInterceptors>
                <bean class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor"></bean>
                <bean class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
                    <constructor-arg>
                        <map>
                            <entry key="action" value="UsernameToken" />
                            <entry key="passwordType" value="PasswordText" />
                            <entry key="passwordCallbackClass" value="com.company.auth.service.ServerPasswordCallback"></entry>
                        </map>
                    </constructor-arg>
                </bean>
            </jaxws:inInterceptors>
        </jaxws:endpoint>

    </beans>

此文件用于服务器配置

client.java

    import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
    import com.company.auth.bean.Employee;
    import com.company.auth.service.AuthService;

    public class Client {

        public Client() {
            super();
        }

        public static void main(String[] args) {
            JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
            factory.setServiceClass(AuthService.class);
            factory.setAddress("http://localhost:8080/CXFSOAP-WebService/corporateAuth");
            AuthService client = (AuthService) factory.create();
            Employee employee = client.getEmployee("22222");
            System.out.println("Server said: "+employee.getLastName()+" "+employee.getFirstName());
            System.exit(0);
        }
    }

这是使用soap web服务的客户端代码。

在添加安全配置之前,服务器已经启动并运行,客户端成功地使用了soap api的功能,但是在安全修改之后,当客户端尝试使用web服务功能时,我会出现以下错误

    org.apache.cxf.binding.soap.SoapFault: A security error was encountered when verifying the message
    at org.apache.cxf.ws.security.wss4j.WSS4JUtils.createSoapFault(WSS4JUtils.java:216)
    at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessageInternal(WSS4JInInterceptor.java:329)
    at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessage(WSS4JInInterceptor.java:184)
    at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessage(WSS4JInInterceptor.java:93)
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
    at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)

原因:org.apache.wss4j.common.ext.WSSecurityException:处理标头时发现错误

    at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.checkActions(WSS4JInInterceptor.java:370)
    at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessageInternal(WSS4JInInterceptor.java:313)
    ... 34 more

我尝试在soap信封中手动添加一些wsse头,但没有成功。

共有1个答案

融唯
2023-03-14

我通过修改authServiceFactory.java类和ClientPasswordCallback.java以及描述符部署文件来解决问题,并添加了auth2_fr_fr.properties文件。

authServiceFactory.java

    import org.springframework.context.support.ClassPathXmlApplicationContext;
    import com.company.auth.bean.Employee;

    public final class AuthServiceFactory {

        private static final ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
                new String[] { "com/company/auth/service/cxfClient.xml" });

        public AuthServiceFactory() {
        }

        public AuthService getService() {
            return (AuthService) context.getBean("client");
        }

        public static void main(String[] args) {
            AuthServiceFactory authSer = new AuthServiceFactory();
            AuthService client = authSer.getService();
            Employee employee = client.getEmployee("22222");
            System.out.println("Server said: " + employee.getLastName() + " " + employee.getFirstName());
            System.exit(0);
        }
}

ClientPasswordCallback.java

    import java.io.IOException;
    import java.util.ResourceBundle;
    import javax.security.auth.callback.Callback;
    import javax.security.auth.callback.CallbackHandler;
    import javax.security.auth.callback.UnsupportedCallbackException;
    import org.apache.wss4j.common.ext.WSPasswordCallback;

    public class ClientPasswordCallback implements CallbackHandler {

        private static final String BUNDLE_LOCATION = "auth2";
        private static final String PASSWORD_PROPERTY_NAME = "auth.manager.password";
        private static String password;

        static {
            final ResourceBundle bundle = ResourceBundle.getBundle(BUNDLE_LOCATION);
            password = bundle.getString(PASSWORD_PROPERTY_NAME);
        }

        @Override
        public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
            WSPasswordCallback pc = (WSPasswordCallback) callbacks[0];
            pc.setPassword(password);
        }
    }

auth2_fr_fr.properties

    auth.manager.password=123456
 类似资料:
  • 日志-消息历史记录路由ID处理器ID处理器运行(ms)[sdPoll][sdPoll][Timer://sdPoll?FixedRate=true&period=60000][21176][null][onCompletion1][onCompletion][106][sdPoll][process7][Ref:RefProcessor][21067][null][process3][Ref:Ge

  • 问题内容: 我不太确定为什么会收到此错误。这是一个基于express.js的简单API,能够添加和删除帖子。当我触发删除路由器时发生错误。我读到错误通常在有两个回调的情况下发生,但是,我似乎找不到任何双重回调。 这是我的posts.js路由器: 问题答案: 您需要添加“返回”,这样您就不会再次回答。

  • 当我使用Ebay API向CreateOrReplaceInventoryItem发出PUT请求时,会出现以下错误: 标头名称使用不当。确保请求标头与HttpRequestMessage一起使用,响应标头与HttpReponseMessage一起使用,内容标头与HttpContent对象一起使用。 然后我得到一个返回的错误对象: 我做错了什么?有没有另一种我不知道的设置内容语言的方法?

  • 我已经通过Spring Boot实现了一个Kafka简单主题消费者,我想使用@KafkaListener注释来获取消息。到目前为止还不错,我对Kafka的方法很满意。我现在面临的问题是,我正在阅读的由第三方发送到这个主题的内容,我认为是由云流绑定生成的,并且有如下标题:ëë½ contentType“text/plain” originalContentType“application/jso

  • 问题内容: 我已经为这个错误苦苦挣扎了一段时间了。 首先,我只是以为是空格,但经过进一步研究,我认为这可能是与此类似的问题: 在此标头语句之前,查找所有可能将输出发送给用户的语句。如果找到一个或多个,请更改代码以将标头语句移到它们之前。复杂的条件语句可能会使问题复杂化,但也可能有助于解决问题。考虑一下PHP脚本顶部的条件表达式,该条件表达式尽早确定标头值并将其设置在那里。 我猜想include标头

  • 问题内容: 我对Node.js相当陌生,遇到了一些问题。 我正在使用Node.js 4.10和Express 2.4.3。 当我尝试访问http://127.0.0.1:8888/auth/facebook时,我将重定向到http://127.0.0.1:8888/auth/facebook_callback。 然后,我收到以下错误: 以下是我的代码: 我可以知道我的代码有什么问题吗? 问题答案: