Infrastructure at your Service

D2-Smartview is a new UI that OpenText now provides starting with the version 16 of D2. It’s a lightweight UI that can perform some of the actions that D2 does. The list of features will probably increase with time but at the moment, I guess it’s more for simple users that have very basic needs, consumer like roles mainly. An interesting thing is that with a small configuration, users can switch between D2 and D2-Smartview on the fly.

 

The issue I wanted to talk about in this blog is a class cast exception that might while trying to download a document using D2-Smartview that has been deployed on a WebLogic Server:

2020-02-21 10:42:11,168 UTC [INFO ] ([ACTIVE] ExecuteThread: '30' for queue: 'weblogic.kernel.Default (self-tuning)') - c.e.d.a.c.documentset.D2DocumentSetSwitch     : D2DocumentSetSwitch.getDocumentSetList end: 0.000s
2020-02-21 10:42:11,184 UTC [INFO ] ([ACTIVE] ExecuteThread: '30' for queue: 'weblogic.kernel.Default (self-tuning)') - com.emc.d2fs.dctm.utils.FormatUtils           : Compiled format pattern [a-zA-Z_\-0-9]+{1,32}
2020-02-21 10:42:11,405 UTC [INFO ] ([ACTIVE] ExecuteThread: '30' for queue: 'weblogic.kernel.Default (self-tuning)') - com.emc.common.dctm.utils.DfServerUtil        : loadBalancedContentServer set to false
2020-02-21 10:42:11,681 UTC [INFO ] ([ACTIVE] ExecuteThread: '95' for queue: 'weblogic.kernel.Default (self-tuning)') - c.e.d.d.w.services.config.D2X3ConfigService   : D2X3ConfigService.getAvailableWidgets end : 0.119s
2020-02-21 10:42:11,903 UTC [ERROR] ([ACTIVE] ExecuteThread: '34' for queue: 'weblogic.kernel.Default (self-tuning)') - com.emc.d2fs.dctm.servlets.D2HttpServlet      : Download could not parse request body
2020-02-21 10:42:11,908 UTC [ERROR] ([ACTIVE] ExecuteThread: '34' for queue: 'weblogic.kernel.Default (self-tuning)') - com.emc.d2fs.dctm.servlets.D2HttpServlet      : Request parsing failed
java.lang.ClassCastException: weblogic.security.principal.WLSUserImpl cannot be cast to com.emc.d2fs.authc.HttpAuthPrincipal
        at com.emc.d2fs.dctm.servlets.D2HttpContext.<init>(D2HttpContext.java:259)
        at com.emc.d2fs.dctm.servlets.D2HttpServlet.doGetAndPost(D2HttpServlet.java:360)
        at com.emc.d2fs.dctm.servlets.D2HttpServlet.doGet(D2HttpServlet.java:113)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:687)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
        at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:286)
        at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:260)
        at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:137)
        at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:350)
        at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:247)
        at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3705)
        at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3672)
        at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:328)
        at weblogic.security.service.SecurityManager.runAsForUserCode(SecurityManager.java:197)
        at weblogic.servlet.provider.WlsSecurityProvider.runAsForUserCode(WlsSecurityProvider.java:203)
        at weblogic.servlet.provider.WlsSubjectHandle.run(WlsSubjectHandle.java:71)
        at weblogic.servlet.internal.WebAppServletContext.doSecuredExecute(WebAppServletContext.java:2443)
        at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2291)
        at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2269)
        at weblogic.servlet.internal.ServletRequestImpl.runInternal(ServletRequestImpl.java:1705)
        at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1665)
        at weblogic.servlet.provider.ContainerSupportProviderImpl$WlsRequestExecutor.run(ContainerSupportProviderImpl.java:272)
        at weblogic.invocation.ComponentInvocationContextManager._runAs(ComponentInvocationContextManager.java:352)
        at weblogic.invocation.ComponentInvocationContextManager.runAs(ComponentInvocationContextManager.java:337)
        at weblogic.work.LivePartitionUtility.doRunWorkUnderContext(LivePartitionUtility.java:57)
        at weblogic.work.PartitionUtility.runWorkUnderContext(PartitionUtility.java:41)
        at weblogic.work.SelfTuningWorkManagerImpl.runWorkUnderContext(SelfTuningWorkManagerImpl.java:652)
        at weblogic.work.ExecuteThread.execute(ExecuteThread.java:420)
        at weblogic.work.ExecuteThread.run(ExecuteThread.java:360)
2020-02-21 10:42:11,931 UTC [ERROR] ([ACTIVE] ExecuteThread: '34' for queue: 'weblogic.kernel.Default (self-tuning)') - com.emc.documentum.rest.util.LogHelper        : LogId: 2516f8e0-f920-437c-86f3-502b3ec8ad14, Status: 500, code: E_INTERNAL_SERVER_ERROR, message: An internal server error occurs.
java.lang.ClassCastException: weblogic.security.principal.WLSUserImpl cannot be cast to com.emc.d2fs.authc.HttpAuthPrincipal
        at com.emc.d2fs.dctm.servlets.D2HttpContext.<init>(D2HttpContext.java:259)
        at com.emc.d2fs.dctm.servlets.D2HttpServlet.doGetAndPost(D2HttpServlet.java:360)
        at com.emc.d2fs.dctm.servlets.D2HttpServlet.doGet(D2HttpServlet.java:113)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:687)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
        at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:286)
        at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:260)
        at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:137)
        at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:350)
        at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:247)
        at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3705)
        at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3672)
        at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:328)
        at weblogic.security.service.SecurityManager.runAsForUserCode(SecurityManager.java:197)
        at weblogic.servlet.provider.WlsSecurityProvider.runAsForUserCode(WlsSecurityProvider.java:203)
        at weblogic.servlet.provider.WlsSubjectHandle.run(WlsSubjectHandle.java:71)
        at weblogic.servlet.internal.WebAppServletContext.doSecuredExecute(WebAppServletContext.java:2443)
        at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2291)
        at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2269)
        at weblogic.servlet.internal.ServletRequestImpl.runInternal(ServletRequestImpl.java:1705)
        at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1665)
        at weblogic.servlet.provider.ContainerSupportProviderImpl$WlsRequestExecutor.run(ContainerSupportProviderImpl.java:272)
        at weblogic.invocation.ComponentInvocationContextManager._runAs(ComponentInvocationContextManager.java:352)
        at weblogic.invocation.ComponentInvocationContextManager.runAs(ComponentInvocationContextManager.java:337)
        at weblogic.work.LivePartitionUtility.doRunWorkUnderContext(LivePartitionUtility.java:57)
        at weblogic.work.PartitionUtility.runWorkUnderContext(PartitionUtility.java:41)
        at weblogic.work.SelfTuningWorkManagerImpl.runWorkUnderContext(SelfTuningWorkManagerImpl.java:652)
        at weblogic.work.ExecuteThread.execute(ExecuteThread.java:420)
        at weblogic.work.ExecuteThread.run(ExecuteThread.java:360)
2020-02-21 10:42:13,972 UTC [ERROR] ([ACTIVE] ExecuteThread: '25' for queue: 'weblogic.kernel.Default (self-tuning)') - c.e.d.d.w.s.b.D2BravaCSRAnnotationService     : Invalid object id:
2020-02-21 10:42:13,978 UTC [ERROR] ([ACTIVE] ExecuteThread: '25' for queue: 'weblogic.kernel.Default (self-tuning)') - c.e.d.d.d.i.D2BravaCSRAnnotationsManagerImpl  : Error getting changemark for document 090f123480003979

 

D2-Smartview is using, in some part, REST services and therefore you might find several similarities between D2-REST and D2-Smartview for example. If you are familiar with the D2-REST application on WebLogic, you might know that OpenText usually asks you to remove a certain set of JARs, then disable some security, aso… It’s not surprising that the documentation for D2-Smartview also asks the same kind of thing. For D2-REST, I personally never had to remove JARs (except this one, which isn’t in the list from OpenText anyway) and I never had to disable the basic authentication. This is because I could always rely on LDAP authentication. Most companies rely on LDAP nowadays and therefore you usually don’t need to disable WebLogic basic authentication on D2-REST because you can just configure WebLogic to use the LDAP Server for authentication and D2-REST will use the same account from the Repository (assuming it is also integrated with the LDAP).

 

Therefore, when I started to do some engineering on D2-Smartview, to deploy and test it, I obviously didn’t follow all the documentation provided by OpenText, only the parts that I usually do for D2-REST because I know that’s sufficient. These are the things that OpenText asks you to do for D2-Smartview 16.5.1 that I simply ignored:

  • Disable web service annotation scan
  • Add “-Dweblogic.servlet.DIDisabled=true” to JVM parameters of the Managed Server
  • Remove JARs files: jsr*.jar, stax-api-*.jar, stax2-api-*.jar, xml-apis-*.jar, xmlParserAPIs-*.jar
  • Disable WebLogic basic authentication: <enforce-valid-basic-auth-credentials>false</enforcevalid-basic-auth-credentials>

 

With the above ignored, I could deploy successfully D2-Smartview 16.5.1. The login was working properly with my LDAP account, I could browse the repository, perform searches, see properties of documents, aso… However, there was one thing not working: the download of document which failed with the above exception. As you can probably tell yourself, the exception is related to class cast exception from WebLogic principal (weblogic.security.principal.WLSUserImpl) to D2-Smartview principal (com.emc.d2fs.authc.HttpAuthPrincipal). Therefore, this was most probably linked to the basic authentication that I kept enabled just like for D2-REST. It looked like for D2-Smartview, it was really needed to disable it.

 

Usually, I don’t like to disable security because you never know… This is especially true for the WebLogic basic authentication because this configuration applies to the whole WebLogic Domain! OpenText claims that disabling the basic authentication on WebLogic isn’t a security issue for their applications (DA, D2, D2-Config, D2-REST, D2-Smartview, d2ls, XMLViewer, DFS, …) because each of these handle the authentication directly. However, at some point in the future, some custom application might be deployed on that domain that expected WebLogic to perform the authentication so you might end-up with security holes. Unfortunately for D2-Smartview, it looks like there is no way around it at the moment (contrary to D2-REST), so disabling the basic authentication is needed if you expect it to work fully:

[[email protected] ~]$ stopDOMAIN

The server 'msDA-01' has been stopped successfully.
The server 'msD2Conf-01' has been stopped successfully.
The server 'msD2SV-01' has been stopped successfully.
The server 'msD2-01' has been stopped successfully.
The server 'AdminServer' has been stopped successfully.
The NodeManager has been stopped successfully.

[[email protected] ~]$
[[email protected] ~]$ grep -A1 "valid-basic" $DOMAIN_HOME/config/config.xml
[[email protected] ~]$
[[email protected] ~]$ sed -i 's,.*</security-configuration>,    <enforce-valid-basic-auth-credentials>false</enforce-valid-basic-auth-credentials>\n&,' $DOMAIN_HOME/config/config.xml
[[email protected] ~]$
[[email protected] ~]$ grep -A1 "valid-basic" $DOMAIN_HOME/config/config.xml
    <enforce-valid-basic-auth-credentials>false</enforce-valid-basic-auth-credentials>
  </security-configuration>
[[email protected] ~]$
[[email protected] ~]$ startDOMAIN

The NodeManager has been started successfully.
The server 'AdminServer' has been started successfully.
The server 'msDA-01' has been started successfully.
The server 'msD2Conf-01' has been started successfully.
The server 'msD2SV-01' has been started successfully.
The server 'msD2-01' has been started successfully.

[[email protected] ~]$

 

As you can see above, I updated the config.xml directly but the preferred way to do it is using WLST. There are several explanations on that on the internet. Once that’s done, the download of files is then working as expected. Maybe OpenText will change the source code so that it doesn’t need that at some point in the future but until then at least, no real other solution. The other three requirements from the documentation are still not in place on my side and I didn’t find anything not working so far so I guess I will just continue to ignore them (especially the “DIDisabled” one).

 

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Morgan Patou
Morgan Patou

Senior Consultant & Technology Leader ECM