繁体   English   中英

WSSecurityException - 发现处理错误的错误 <wsse:Security> 头

[英]WSSecurityException - An error was discovered processing the <wsse:Security> header

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

我得到了An错误被发现处理标题

以下是将安全性方面添加到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

我试图在肥皂信封中手动添加一些wsse标题,但它不起作用。

我通过修改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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM