1
votes

We are hosting a web service (JAX-WS) exposing services via Apache CXF 3.0.1. We have deployed it successfully on IBM WebSphere v8.5.5.5 with the following suggestions:

  • Class loading is set to PARENT_LAST = true
  • DisableIBMJAXWSEngine = true

An excerpt from the bean definition file is as follows:

<jaxws:endpoint id="VPMSWebService"
        implementor="com.xxxxx.CustomServiceImpl" address="/vWebService">
        <jaxws:features>
            <wsa:addressing xmlns:wsa="http://cxf.apache.org/ws/addressing" />
        </jaxws:features>
        <jaxws:properties>
            <entry key="jaxb-validation-event-handler">
                <bean class="com.xxxxx.CXFValidationEventHandler" />
            </entry>
        </jaxws:properties>     
        <jaxws:inInterceptors>
            <bean class="com.xxxxxx.IncomingAuthenticationInterceptor"/>
        </jaxws:inInterceptors>
        <jaxws:inFaultInterceptors>
            <bean class="com.xxxxx.IncomingAuthenticationFaultInterceptor"/>
        </jaxws:inFaultInterceptors>      
        <jaxws:handlers>
            <bean class="com.xxxxxxx.interceptors.AuthenticationHandler"/>
        </jaxws:handlers>  
</jaxws:endpoint>

Basic Authentication is being introduced in a declarative manner inside the deployment descriptor as follows:

<security-constraint>
    <web-resource-collection>
        <web-resource-name>web service resource</web-resource-name>
        <url-pattern>/*</url-pattern>
        <http-method>GET</http-method>
        <http-method>POST</http-method>     
    </web-resource-collection>
    <auth-constraint>
        <role-name>SvcLayerUser</role-name>
    </auth-constraint>
    <user-data-constraint>
        <transport-guarantee>NONE</transport-guarantee>
    </user-data-constraint>
  </security-constraint>
  <security-role>
    <role-name>SvcLayerUser</role-name>
  </security-role>
  <login-config>
    <auth-method>BASIC</auth-method>
    <realm-name>Authentication</realm-name>
  </login-config>

When the service is invoked using SOAPUI as a client with correct username/password pair, the invocation is normal and proper SOAP response is returned to the calling program. If the issue lies with the XML, SOAP Fault is returned respectively. With Debugging ON, we can navigate the complete flow of the application.

Problem arises when we pass either a wrong username or wrong password. Then the WebSphere container simply handles the authentication, passes a 401 HTTP status code to SOAPUI with no contents. None of the CXF based interceptors or handlers ever get invoked.

[9/18/18 4:23:05:439 EDT] 00000082 FfdcProvider W com.ibm.ws.ffdc.impl.FfdcProvider logIncident FFDC1003I: FFDC Incident emitted on E:\WAS8.5\IBM\WebSphere\AppServer\profiles\AppSrv20\logs\ffdc\server1_4c0ec188_18.09.18_04.23.05.3929133721879993856345.txt com.ibm.websphere.security.PasswordCheckFailedException 190 [9/18/18 4:23:05:454 EDT] 00000082 DMAdapter I com.ibm.ws.ffdc.impl.DMAdapter getAnalysisEngine FFDC1009I: Analysis Engine using data base: E:\WAS8.5\IBM\WebSphere\AppServer\properties\logbr\ffdc\adv\ffdcdb.xml [9/18/18 4:23:05:470 EDT] 00000082 FfdcProvider W com.ibm.ws.ffdc.impl.FfdcProvider logIncident FFDC1003I: FFDC Incident emitted on E:\WAS8.5\IBM\WebSphere\AppServer\profiles\AppSrv20\logs\ffdc\server1_4c0ec188_18.09.18_04.23.05.3924076528169475779324.txt com.ibm.ws.security.ltpa.LTPAServerObject.authenticate 1020 [9/18/18 4:23:05:470 EDT] 00000082 LTPAServerObj E SECJ0369E: Authentication failed when using LTPA. The exception is com.ibm.websphere.wim.exception.PasswordCheckFailedException: CWWIM4513E The password match failed for the 'bob' principal name.. [9/18/18 4:23:05:485 EDT] 00000082 FfdcProvider W com.ibm.ws.ffdc.impl.FfdcProvider logIncident FFDC1003I: FFDC Incident emitted on E:\WAS8.5\IBM\WebSphere\AppServer\profiles\AppSrv20\logs\ffdc\server1_4c0ec188_18.09.18_04.23.05.4701707172482039548991.txt com.ibm.websphere.security.auth.WSLoginFailedException 250 [9/18/18 4:23:05:485 EDT] 00000082 FfdcProvider W com.ibm.ws.ffdc.impl.FfdcProvider logIncident FFDC1003I: FFDC Incident emitted on E:\WAS8.5\IBM\WebSphere\AppServer\profiles\AppSrv20\logs\ffdc\server1_4c0ec188_18.09.18_04.23.05.4703645264312534190424.txt com.ibm.ws.security.server.lm.ltpaLoginModule.login 452 [9/18/18 4:23:05:485 EDT] 00000082 FfdcProvider W com.ibm.ws.ffdc.impl.FfdcProvider logIncident FFDC1003I: FFDC Incident emitted on E:\WAS8.5\IBM\WebSphere\AppServer\profiles\AppSrv20\logs\ffdc\server1_4c0ec188_18.09.18_04.23.05.4859153488925589622788.txt com.ibm.ws.security.server.lm.wsMapDefaultInboundLoginModule.login 860 [9/18/18 4:23:05:501 EDT] 00000082 FfdcProvider W com.ibm.ws.ffdc.impl.FfdcProvider logIncident FFDC1003I: FFDC Incident emitted on E:\WAS8.5\IBM\WebSphere\AppServer\profiles\AppSrv20\logs\ffdc\server1_4c0ec188_18.09.18_04.23.05.4853176694169720358643.txt com.ibm.ws.security.auth.JaasLoginHelper.jaas_login 503 [9/18/18 4:23:05:501 EDT] 00000082 FfdcProvider W com.ibm.ws.ffdc.impl.FfdcProvider logIncident FFDC1003I: FFDC Incident emitted on E:\WAS8.5\IBM\WebSphere\AppServer\profiles\AppSrv20\logs\ffdc\server1_4c0ec188_18.09.18_04.23.05.5012191986958630799174.txt com.ibm.ws.security.auth.ContextManagerImpl.login 4948 [9/18/18 4:23:05:641 EDT] 00000082 LTPAServerObj E SECJ0369E: Authentication failed when using LTPA. The exception is com.ibm.websphere.wim.exception.PasswordCheckFailedException: CWWIM4513E The password match failed for the 'bob' principal name..

Ffdc log file has

[9/18/18 4:23:05:470 EDT] FFDC Exception:com.ibm.websphere.security.auth.WSLoginFailedException SourceId:com.ibm.ws.security.server.lm.ltpaLoginModule.login ProbeId:452 Reporter:com.ibm.ws.security.server.lm.ltpaLoginModule@a2cacf0e com.ibm.websphere.wim.exception.PasswordCheckFailedException: CWWIM4513E The password match failed for the 'bob' principal name. at com.ibm.ws.wim.adapter.file.was.FileAdapter.login(FileAdapter.java:2455) at com.ibm.ws.wim.ProfileManager.loginImpl(ProfileManager.java:3859) at com.ibm.ws.wim.ProfileManager.genericProfileManagerMethod(ProfileManager.java:360) at com.ibm.ws.wim.ProfileManager.login(ProfileManager.java:468) at com.ibm.websphere.wim.ServiceProvider.login(ServiceProvider.java:545) at com.ibm.ws.wim.registry.util.LoginBridge.checkPassword(LoginBridge.java:194) at com.ibm.ws.wim.registry.WIMUserRegistry$1.run(WIMUserRegistry.java:270) at com.ibm.ws.wim.registry.WIMUserRegistry$1.run(WIMUserRegistry.java:262) at com.ibm.ws.security.auth.ContextManagerImpl.runAs(ContextManagerImpl.java:5554) at com.ibm.ws.security.auth.ContextManagerImpl.runAsSystem(ContextManagerImpl.java:5680) at com.ibm.ws.wim.security.authz.jacc.JACCSecurityManager.runAsSuperUser(JACCSecurityManager.java:438) at com.ibm.ws.wim.env.was.JACCAuthorizationService.runAsSuperUser(JACCAuthorizationService.java:1086) at com.ibm.ws.wim.security.authz.ProfileSecurityManager.runAsSuperUser(ProfileSecurityManager.java:285) at com.ibm.ws.wim.registry.WIMUserRegistry.checkPassword(WIMUserRegistry.java:261) at com.ibm.ws.security.registry.UserRegistryImpl.checkPassword(UserRegistryImpl.java:394) at com.ibm.ws.security.ltpa.LTPAServerObject.authenticate(LTPAServerObject.java:997) at com.ibm.ws.security.server.lm.ltpaLoginModule.login(ltpaLoginModule.java:660) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:95) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:56) at java.lang.reflect.Method.invoke(Method.java:620) at javax.security.auth.login.LoginContext.invoke(LoginContext.java:781) at javax.security.auth.login.LoginContext.access$000(LoginContext.java:215) at javax.security.auth.login.LoginContext$4.run(LoginContext.java:706) at javax.security.auth.login.LoginContext$4.run(LoginContext.java:704) at java.security.AccessController.doPrivileged(AccessController.java:488) at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:703) at javax.security.auth.login.LoginContext.login(LoginContext.java:609) at com.ibm.ws.security.auth.JaasLoginHelper.jaas_login(JaasLoginHelper.java:491) at com.ibm.ws.security.auth.ContextManagerImpl.login(ContextManagerImpl.java:4892) at com.ibm.ws.security.auth.ContextManagerImpl.login(ContextManagerImpl.java:4494) at com.ibm.ws.security.auth.ContextManagerImpl.login(ContextManagerImpl.java:4490) at com.ibm.ws.security.web.WebAuthenticator.basicAuthenticate(WebAuthenticator.java:3722) at com.ibm.ws.security.web.WebAuthenticator.handleBasicAuth(WebAuthenticator.java:2869) at com.ibm.ws.security.web.WebAuthenticator.authenticate(WebAuthenticator.java:3235) at com.ibm.ws.security.web.WebCollaborator.SetAuthenticatedSubjectIfNeeded(WebCollaborator.java:3232) at com.ibm.ws.security.web.WebCollaborator.authorize(WebCollaborator.java:716) at com.ibm.ws.security.web.EJSWebCollaborator.preInvoke(EJSWebCollaborator.java:446) at com.ibm.ws.webcontainer.collaborator.WebAppSecurityCollaboratorImpl.preInvoke(WebAppSecurityCollaboratorImpl.java:230) at com.ibm.wsspi.webcontainer.collaborator.CollaboratorHelper.preInvokeCollaborators(CollaboratorHelper.java:436) at com.ibm.ws.webcontainer.filter.WebAppFilterManager.invokeFilters(WebAppFilterManager.java:1089) at com.ibm.ws.webcontainer.webapp.WebApp.handleRequest(WebApp.java:4028) at com.ibm.ws.webcontainer.webapp.WebGroup.handleRequest(WebGroup.java:304) at com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:1016) at com.ibm.ws.webcontainer.WSWebContainer.handleRequest(WSWebContainer.java:1817) at com.ibm.ws.webcontainer.channel.WCChannelLink.ready(WCChannelLink.java:200) at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleDiscrimination(HttpInboundLink.java:463) at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleNewRequest(HttpInboundLink.java:530) at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.processRequest(HttpInboundLink.java:316) at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.ready(HttpInboundLink.java:287) at com.ibm.ws.tcp.channel.impl.NewConnectionInitialReadCallback.sendToDiscriminators(NewConnectionInitialReadCallback.java:214) at com.ibm.ws.tcp.channel.impl.NewConnectionInitialReadCallback.complete(NewConnectionInitialReadCallback.java:113) at com.ibm.ws.tcp.channel.impl.AioReadCompletionListener.futureCompleted(AioReadCompletionListener.java:175) at com.ibm.io.async.AbstractAsyncFuture.invokeCallback(AbstractAsyncFuture.java:217) at com.ibm.io.async.AsyncChannelFuture.fireCompletionActions(AsyncChannelFuture.java:161) at com.ibm.io.async.AsyncFuture.completed(AsyncFuture.java:138) at com.ibm.io.async.ResultHandler.complete(ResultHandler.java:204) at com.ibm.io.async.ResultHandler.runEventProcessingLoop(ResultHandler.java:775) at com.ibm.io.async.ResultHandler$2.run(ResultHandler.java:905) at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1892)

Main Questions are:

  1. How come our CXF based components are not getting invoked when an exception happens for bad username or bad password? Why WebSphere container raises an exception and return controls back to caller directly?

  2. What changes we should make on our EAR to handle the above WAS container exception so we can make it a detailed SOAP fault and return to the caller with more information?

1
Pleas edit your question ans put linebreaks in it, so the readability becomes better. Use quotes (prepend a > in front of the line) to highlight things you are quoting, use backticks (`) to highlight code. Make it more pleasant to read. Only in that case you will get an answer.hellow
Sure, you could improve the formatting some, but I don't think formatting is an issue here. On the other hand, it would help to show your code so far, what you have tried. Are you using a "javax.xml.ws.handler.soap.SOAPHandler"? (Show this detail). It's hard to understand this statement too Websphere container is not passing the control to our code where we have handlers code but none of them are getting activated. If that's what you meant, maybe elaborate on that (why you know that to be true, etc.).Scott Kurz
just reword the whole problem so please review.MKhan

1 Answers

0
votes

As you are doing the basic authentication, it is checked at server infrastructure even before it reaches webcontainer, and since container already knows that your user is not authenticated, it doesn't even call web service engine.

You would need to customize login process to intercept that request (e.g custom login module), or implement whole login logic in your handler (e.g. calling WSLogin), both are too broad to discussed here.

For a start you can check this page Advanced authentication in WebSphere Application Server

Both are complex solutions, so I'd strongly advise against it, as currently, you are returning clear message that request was not authenticated any way, and as it is WS call, you really dont need to provide any custom, human readable message for that. Moreover, revealing more details "why authentication failed" weakens your security, gives more information to the attacker and is in general not recommended.