camel cxf ws-security implementation jboss eap

时间:2018-01-26 17:27:10

标签: apache-camel cxf ws-security jbossfuse jboss-eap-6

我正在尝试使用WS-Security UsernameToken实现对webservice的身份验证和授权。

Camel version 2.17
Jboss fuse 6.3
Jboss RAP 6.4.17

我已将我的用户名,密码和角色存储在JBoss EAP服务器的应用领域中。

我在org.apache.wss4j.common.cache.EHCacheManagerHolder中获取nullpointer

我在配置中遗漏了什么吗?

GIT中的项目位置:

https://github.com/ravi21588/SO/tree/master/authenticationpoc

使用ws-secutiry标头的肥皂请求:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:exam="http://Example.org">
   <soapenv:Header>
    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
         <wsse:UsernameToken>
            <wsse:Username>Harish</wsse:Username>
            <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">5p[#rnZc!mB[)]8{</wsse:Password>
         </wsse:UsernameToken>
      </wsse:Security>
    </soapenv:Header>
   <soapenv:Body>
      <exam:Add>
         <!--Optional:-->
         <exam:a>10</exam:a>
         <!--Optional:-->
         <exam:b>11</exam:b>
      </exam:Add>
   </soapenv:Body>
</soapenv:Envelope>

Server.log:

18:15:30,688 WARNING [org.apache.cxf.phase.PhaseInterceptorChain] (http-127.0.0.1:8443-1) Interceptor for {http://Example.org}CalculatorService#{http://Example.org}Add has thrown exception, unwinding now: java.lang.NullPointerException
        at org.apache.wss4j.common.cache.EHCacheManagerHolder.getCacheManager(EHCacheManagerHolder.java:106)
        at org.apache.cxf.ws.security.cache.EHCacheUtils.getCacheManager(EHCacheUtils.java:49) [cxf-rt-ws-security-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
        at org.apache.cxf.ws.security.cache.CXFEHCacheReplayCache.<init>(CXFEHCacheReplayCache.java:37) [cxf-rt-ws-security-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
        at org.apache.cxf.ws.security.wss4j.WSS4JUtils.getReplayCache(WSS4JUtils.java:126) [cxf-rt-ws-security-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
        at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.getReplayCache(WSS4JInInterceptor.java:637) [cxf-rt-ws-security-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
        at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.configureReplayCaches(WSS4JInInterceptor.java:404) [cxf-rt-ws-security-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
        at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessageInternal(WSS4JInInterceptor.java:237) [cxf-rt-ws-security-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
        at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessage(WSS4JInInterceptor.java:171) [cxf-rt-ws-security-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
        at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessage(WSS4JInInterceptor.java:80) [cxf-rt-ws-security-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
        at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308) [cxf-core-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
        at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121) [cxf-core-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
        at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:254) [cxf-rt-transports-http-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
        at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:234) [cxf-rt-transports-http-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
        at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:208) [cxf-rt-transports-http-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
        at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:160) [cxf-rt-transports-http-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
        at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:180) [cxf-rt-transports-http-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
        at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:299) [cxf-rt-transports-http-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
        at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:218) [cxf-rt-transports-http-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:754) [jboss-servlet-api_3.0_spec-1.0.2.Final-redhat-2.jar:1.0.2.Final-redhat-2]
        at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:274) [cxf-rt-transports-http-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:295) [jbossweb-7.5.24.Final-redhat-1.jar:7.5.24.Final-redhat-1]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214) [jbossweb-7.5.24.Final-redhat-1.jar:7.5.24.Final-redhat-1]
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:231) [jbossweb-7.5.24.Final-redhat-1.jar:7.5.24.Final-redhat-1]
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:149) [jbossweb-7.5.24.Final-redhat-1.jar:7.5.24.Final-redhat-1]
        at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:169) [jboss-as-web-7.5.17.Final-redhat-4.jar:7.5.17.Final-redhat-4]
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:151) [jbossweb-7.5.24.Final-redhat-1.jar:7.5.24.Final-redhat-1]
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:97) [jbossweb-7.5.24.Final-redhat-1.jar:7.5.24.Final-redhat-1]
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:102) [jbossweb-7.5.24.Final-redhat-1.jar:7.5.24.Final-redhat-1]
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [jbossweb-7.5.24.Final-redhat-1.jar:7.5.24.Final-redhat-1]
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:856) [jbossweb-7.5.24.Final-redhat-1.jar:7.5.24.Final-redhat-1]
        at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:656) [jbossweb-7.5.24.Final-redhat-1.jar:7.5.24.Final-redhat-1]
        at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:926) [jbossweb-7.5.24.Final-redhat-1.jar:7.5.24.Final-redhat-1]
        at java.lang.Thread.run(Thread.java:748) [rt.jar:1.8.0_151]

vadim suggetion实现后的服务器日志:

10:01:40,322 WARNING [org.apache.cxf.phase.PhaseInterceptorChain] (http-127.0.0.1:8080-4) Interceptor for {http://Example.org}CalculatorService#{http://Example.org}Add has thrown exception, unwinding now: org.apache.cxf.interceptor.security.AuthenticationException: Authentication failed (details can be found in server log)
    at org.apache.cxf.interceptor.security.JAASLoginInterceptor.handleMessage(JAASLoginInterceptor.java:171) [cxf-core-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308) [cxf-core-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
    at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121) [cxf-core-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
    at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:254) [cxf-rt-transports-http-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
    at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:234) [cxf-rt-transports-http-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
    at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:208) [cxf-rt-transports-http-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
    at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:160) [cxf-rt-transports-http-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
    at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:180) [cxf-rt-transports-http-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
    at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:299) [cxf-rt-transports-http-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
    at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:218) [cxf-rt-transports-http-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:754) [jboss-servlet-api_3.0_spec-1.0.2.Final-redhat-2.jar:1.0.2.Final-redhat-2]
    at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:274) [cxf-rt-transports-http-3.1.5.redhat-630310.jar:3.1.5.redhat-630310]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:295) [jbossweb-7.5.24.Final-redhat-1.jar:7.5.24.Final-redhat-1]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214) [jbossweb-7.5.24.Final-redhat-1.jar:7.5.24.Final-redhat-1]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:231) [jbossweb-7.5.24.Final-redhat-1.jar:7.5.24.Final-redhat-1]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:149) [jbossweb-7.5.24.Final-redhat-1.jar:7.5.24.Final-redhat-1]
    at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:169) [jboss-as-web-7.5.17.Final-redhat-4.jar:7.5.17.Final-redhat-4]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:151) [jbossweb-7.5.24.Final-redhat-1.jar:7.5.24.Final-redhat-1]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:97) [jbossweb-7.5.24.Final-redhat-1.jar:7.5.24.Final-redhat-1]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:102) [jbossweb-7.5.24.Final-redhat-1.jar:7.5.24.Final-redhat-1]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [jbossweb-7.5.24.Final-redhat-1.jar:7.5.24.Final-redhat-1]
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:856) [jbossweb-7.5.24.Final-redhat-1.jar:7.5.24.Final-redhat-1]
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:656) [jbossweb-7.5.24.Final-redhat-1.jar:7.5.24.Final-redhat-1]
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:926) [jbossweb-7.5.24.Final-redhat-1.jar:7.5.24.Final-redhat-1]
    at java.lang.Thread.run(Thread.java:748) [rt.jar:1.8.0_151]

1 个答案:

答案 0 :(得分:1)

为此,您可以使用org.apache.cxf.interceptor.security.JAASLoginInterceptor

中自己的扩展程序

一般来说,这很简单。您需要向JAASLoginInterceptor提供org.apache.cxf.interceptor.security.NamePasswordCallbackHandler的实例。

你必须做3个步骤:

Step1:拦截器:

package com.foo.security;
import javax.security.auth.callback.CallbackHandler;
import org.apache.cxf.interceptor.security.JAASLoginInterceptor;
import org.apache.cxf.interceptor.security.NamePasswordCallbackHandler;

public class CustomJAASLoginInterceptor extends JAASLoginInterceptor {
  @Override
  protected CallbackHandler getCallbackHandler(String name, String password) {
    return new NamePasswordCallbackHandler(name, password, "setCredential");
  }
}

步骤2:然后在Camel-Cxf端点(或在CXF总线中)定义该拦截器:

<cxf-core:inInterceptors xmlns:cxf-core="http://cxf.apache.org/core">
        <spring:bean id="authenticationInterceptor"             
           class="com.foo.security.CustomJAASLoginInterceptor">
        </spring:bean>
</cxf-core:inInterceptors>

步骤3:再次在相同的Camel-Cxf端点(或在CXF总线中)将WSS4J的消息认证委托给JAASLoginInterceptor:

<cxf-core:properties>
        <!-- delegate message authentication out of WSS4J to JAASLoginInterceptor -->
        <spring:entry key="ws-security.validate.token" value="false" />
        <!-- ... other properties -->
<cxf-core:properties>

毕竟它可以与EAP应用领域中定义的用户无缝地使用JBoss EAP JAAS。

更新1:

看起来您必须在standalone.xml(或domain.xml)中为ApplicationRealm定义其他安全域和Login模块。我不确定哪一个负责WebServices,所以我在standalone.xml中有什么

<subsystem xmlns="urn:jboss:domain:security:1.2">
   ...
   <security-domain name="jboss-web-policy" cache-type="default">
                <authentication>
                    <login-module code="RealmDirect" flag="optional">
                        <module-option name="realm" value="ApplicationRealm"/>
                        <module-option name="password-stacking" value="useFirstPass"/>
                    </login-module>
                </authentication>
                <authorization>
                    <policy-module code="Delegating" flag="required"/>
                </authorization>
   </security-domain>

   <security-domain name="other" cache-type="default">
                <authentication>
                    <login-module code="RealmDirect" flag="optional">
                        <module-option name="realm" value="ApplicationRealm"/>
                        <module-option name="password-stacking" value="useFirstPass"/>
                    </login-module>
                    <login-module code="Remoting" flag="optional">
                        <module-option name="password-stacking" value="useFirstPass"/>
                    </login-module>
                </authentication>
                <authorization>
                    <policy-module code="Web" flag="sufficient"/>
                    <policy-module code="Delegating" flag="sufficient"/>
                </authorization>
    </security-domain>

我看到我的工作standalone.xml与EAP安装提供的默认工具之间没有太多差异。

更新2

因此,工作WSSE头(由SoapUI构建)看起来像:

<soap:Header xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <wsse:Security  soap:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
    <wsse:UsernameToken wsu:Id="UsernameToken-45417D5A3EF19629C315173319098351">
        <wsse:Username>my_username</wsse:Username>
        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">my_password</wsse:Password>
        <wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">qY0N9DfYcd7kQfBkfNilRw==</wsse:Nonce>
        <wsu:Created>2018-01-30T17:05:09.835Z</wsu:Created>
    </wsse:UsernameToken>
  </wsse:Security>
</soap:Header>

P.S。它也可以不使用nonce和timestamp,但最好使用它们。