Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

java.lang.NoClassDefFoundError: when using JDBC Security Realm for authentication #1675

Closed
Scoty opened this issue Jun 13, 2017 · 5 comments
Closed

Comments

@Scoty
Copy link

Scoty commented Jun 13, 2017

Description


java.lang.NoClassDefFoundError: com/sun/appserv/security/ProgrammaticLogin when using JDBC security realm for a webapp authentication.

Using the same security realm's configuration works in GlassFish 3.1.2.2. (The same machine, the same MySQL server and DB and I have copied the security realm configuration lines from the GlassFish 3.1.2.2's domain.xml to the Payara's domain.xm)

Expected Outcome

Being able to use the configured JDBC security realm for a webapp security management.

Current Outcome

StandardWrapperValve[action]: Servlet.service() for servlet action threw exception
java.lang.NoClassDefFoundError: com/sun/appserv/security/ProgrammaticLogin
        at com.safecharge.------------REMOVED-------------.LoginAction.execute(LoginAction.java:117)
        at org.apache.struts.chain.commands.servlet.ExecuteAction.execute(ExecuteAction.java:58)
        at org.apache.struts.chain.commands.AbstractExecuteAction.execute(AbstractExecuteAction.java:67)
        at org.apache.struts.chain.commands.ActionCommandBase.execute(ActionCommandBase.java:51)
        at org.apache.commons.chain.impl.ChainBase.execute(ChainBase.java:191)
        at org.apache.commons.chain.generic.LookupCommand.execute(LookupCommand.java:305)
        at org.apache.commons.chain.impl.ChainBase.execute(ChainBase.java:191)
        at org.apache.struts.chain.ComposableRequestProcessor.process(ComposableRequestProcessor.java:283)
        at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1913)
        at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:462)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
        at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1606)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:338)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
        at org.displaytag.filter.ResponseOverrideFilter.doFilter(ResponseOverrideFilter.java:125)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:250)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:256)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
        at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:654)
        at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:593)
        at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155)
        at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:371)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:238)
        at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:466)
        at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:169)
        at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:206)
        at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:180)
        at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235)
        at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
        at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284)
        at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201)
        at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133)
        at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112)
        at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
        at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:539)
        at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
        at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
        at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
        at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
        at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:593)
        at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:573)
        at java.lang.Thread.run(Thread.java:748)

Steps to reproduce (Only for bug reports)

  1. OPTIONAL: Create a JDBC Security realm in Payara(Configurations -> server-config -> Security -> Realms).
  2. Create a simple webapp which uses com.sun.appserv.security.ProgrammaticLogin programmaticLogin = new ProgrammaticLogin();
  3. Deploy the app and reach the above line, It will throw the exception. OPTIONAL: implement the full security realm authentication logic.

Samples

Part of the maven-glassfish-plugin configuration used for creating the realm:

<auth>
	<realm>
		<name>PPP_REMOVED</name>
		<className>com.sun.enterprise.security.auth.realm.jdbc.JDBCRealm</className>
		<properties>
			<property>
				<name>digest-algorithm</name>
				<value>MD5</value>
			</property>
			<property>
				<name>user-name-column</name>
				<value>not deleted AND PPP_REMOVED</value>
			</property>
			<property>
				<name>password-column</name>
				<value>PPP_REMOVED</value>
			</property>
			<property>
				<name>group-name-column</name>
				<value>PPP_REMOVED</value>
			</property>
			<property>
				<name>group-table</name>
				<value>PPP_REMOVED</value>
			</property>
			<property>
				<name>user-table</name>
				<value>PPP_REMOVED</value>
			</property>
			<property>
				<name>datasource-jndi</name>
				<value>jdbc_PPP_REMOVED</value>
			</property>
			<property>
				<name>jaas-context</name>
				<value>jdbcRealm</value>
			</property>
		</properties>
	</realm>
</auth>

Context (Optional)

Use com.sun.enterprise.security.auth.realm.jdbc.JDBCRealm for authentication.

Environment

  • Payara Version: 4.1.2.172 #badassfish (build 235)
  • Edition: Full
  • JDK Version: Oracle JDK8 u131
  • Operating System: Windows 10
  • Database: MySQL
@Scoty
Copy link
Author

Scoty commented Jun 13, 2017

It seems to be due to the fact that ProgrammaticLogin has been moved from com.sun.appserv.security.ProgrammaticLogin to com.sun.enterprise.security.ee.auth.login.ProgrammaticLogin.

Adding the following dependency:

<dependency>
	<groupId>org.glassfish.main.security</groupId>
	<artifactId>security-ee</artifactId>
	<version>4.1.2</version>
	<scope>provided</scope>
</dependency>

and using com.sun.enterprise.security.ee.auth.login.ProgrammaticLogin seems to fix the problem.

@arjantijms
Copy link
Contributor

@Scoty where are you using ProgrammaticLogin exactly for? Can you show the line where you call a method on programmaticLogin?

For most cases in a web environment it has been replaced by the Java EE spec compliant HttpServletRequest#login, and HttpServletRequest#authenticate

@Scoty
Copy link
Author

Scoty commented Jun 13, 2017

It is inside of a login action from a legacy Struts(1.x) application:

 ProgrammaticLogin programmaticLogin = new ProgrammaticLogin();
        try {
            boolean login = programmaticLogin.login(username, password, 
            PPP_CONST_HOLDING_THE_REALM_NAME, request, response, true);
            logger.info("##### LoginAction login: " + login);
            if (login) {
                // do some crap and findForward() to the index page
            }

May be someday this code will get rewritten, but until then that is the implementation and my above post is the workaround ...

Still it is not a bug with Payara, just a problem that occurs when migrating from old GlassFish JavaEE implementation to the new (GF4+ or Payara).

@arjantijms
Copy link
Contributor

Okay, thanks for mentioning the workaround ;)

Indeed, this extended version where the realm name is mentioned isn't supported by the Java EE spec version (since realms, aka identity stores were never standardised).

@fturizo
Copy link
Contributor

fturizo commented Jun 15, 2017

Closing this issue since the main problem is not a bug on Payara Server and the user is aware of the risks of using internal API classes instead of the standard mechanisms.

@fturizo fturizo closed this as completed Jun 15, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants