Thanks for the input Jan. You are totally correct, I was missing the Neo4j jar 
file in the server class path. I suspect that would have been the next problem 
I ran in to once I got the login module so it was using the server class 
loader.  I updated the instructions in the repo to reflect your comments.  
Thank you very much and sorry for the gaps there. I am the only person, to my 
knowledge, who has attempted to use this so the docs were a little lacking.
I made sure the Neo4j driver was in the server class path. I did this by adding 
the jar file to the JETTY_BASE/lib/ext directory;
find lib/*

lib/ext

lib/ext/postgresql-42.2.18.jar

lib/ext/neo4j-java-driver-4.4.12.jar

lib/neo4j_login_module-1.0.jar

lib/reload_sslkey_module-1.3.jar


However, I still see the same problem I had before. The trick is I am 
successfully connecting to the Neo4j database and authenticating the user.  But 
after this is completed, when creating the Credential, I am running in to the 
class loader problem.
java.lang.NoClassDefFoundError: org/eclipse/jetty/util/security/Credential

Before adding the neo4j driver to the server class path, I suspect I was 
finding the Neo4j classes because my login module is being loaded in the 
context of my webapp for some reason. The webapp class loader had the Neo4j 
driver. If I could get my login module to run in the server class loader 
context, then  I am sure I would have seen the problem you identified.
Is there anything I can do to get my login module to run in the context of the 
server class loader? 
I am not familiar with the demo JAAS webapp, I might look in to that and see if 
I can learn something there. 
Scott

    On Tuesday, January 23, 2024, 11:25:50 PM PST, Jan Bartel 
<j...@webtide.com> wrote:  
 
 Scott,
I followed the instructions on your repo. However, instead of copying a .ini 
file into start.d, I just let jetty do it with:
java -jar ../jetty-home/start.jar --add-module=neo4j-authentication
When I run the jetty demo jaas webapp using your module and hit the 
authentication form, I get:
java.lang.NoClassDefFoundError: org/neo4j/driver/AuthTokens
        at 
com.bb.neo4j_login_module.Neo4jLoginModule.getUser(Neo4jLoginModule.java:276)
        at 
com.bb.neo4j_login_module.Neo4jLoginModule.login(Neo4jLoginModule.java:133)
        at 
java.base/javax.security.auth.login.LoginContext.invoke(LoginContext.java:755)
        at 
java.base/javax.security.auth.login.LoginContext$4.run(LoginContext.java:679)
        at 
java.base/javax.security.auth.login.LoginContext$4.run(LoginContext.java:677)
        at 
java.base/java.security.AccessController.doPrivileged(AccessController.java:712)
        at 
java.base/javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:677)
        at 
java.base/javax.security.auth.login.LoginContext.login(LoginContext.java:587)
        at 
org.eclipse.jetty.jaas.JAASLoginService.login(JAASLoginService.java:214)
        at 
org.eclipse.jetty.security.authentication.LoginAuthenticator.login(LoginAuthenticator.java:62)
        at 
org.eclipse.jetty.security.authentication.FormAuthenticator.login(FormAuthenticator.java:173)
        at 
org.eclipse.jetty.security.authentication.FormAuthenticator.validateRequest(FormAuthenticator.java:262)
        at 
org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:528)
        at 
org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122)
        at 
org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:223)
        at 
org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1580)
        at 
org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:221)
        at 
org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1381)
        at 
org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:176)
        at 
org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:484)
        at 
org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1553)
        at 
org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:174)
        at 
org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1303)
        at 
org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:129)
        at 
org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:192)
        at 
org.eclipse.jetty.server.handler.HandlerList.handle(HandlerList.java:51)
        at 
org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122)
        at 
org.eclipse.jetty.rewrite.handler.RewriteHandler.handle(RewriteHandler.java:301)
        at 
org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122)
        at org.eclipse.jetty.server.Server.handle(Server.java:563)
        at 
org.eclipse.jetty.server.HttpChannel$RequestDispatchable.dispatch(HttpChannel.java:1598)
        at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:753)
        at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:501)
        at 
org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:287)
        at 
org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:314)
        at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:100)
        at 
org.eclipse.jetty.io.SelectableChannelEndPoint$1.run(SelectableChannelEndPoint.java:53)
        at 
org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.runTask(AdaptiveExecutionStrategy.java:421)
        at 
org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.consumeTask(AdaptiveExecutionStrategy.java:390)
        at 
org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.tryProduce(AdaptiveExecutionStrategy.java:277)
        at 
org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.run(AdaptiveExecutionStrategy.java:199)
        at 
org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:411)
        at 
org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:969)
        at 
org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.doRunJob(QueuedThreadPool.java:1194)
        at 
org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1149)
        at java.base/java.lang.Thread.run(Thread.java:1589)
Caused by: java.lang.ClassNotFoundException: org.neo4j.driver.AuthTokens
        at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:445)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:588)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
That's not much of a surprise, as your neo4j login module doesn't put the neo4j 
classes onto the _server_ classpath. Note that they cannot be inside the 
webapp, as the login module is being invoked by the server path, and cannot 
reference classes that exist inside your webapp.
I think if you make a neo4j.mod which puts all of the necessary neo4j jars onto 
the server classpath, then make your neo4j-authentication.mod depend on it, 
then you should be ok.
cheersJan
On Wed, 24 Jan 2024 at 15:11, scottastanley--- via jetty-users 
<jetty-users@eclipse.org> wrote:

I have written a custom LoginModule to authenticate users using nodes in a 
Neo4J graph database. Kind of like the functionality in the provided 
org.eclipse.jetty.jaas.spi.JDBCLoginModule. Basically, provide the node type 
and attributes in the node for the username and password and we can 
authenticate against the graph database. As part of this, I am using the 
following three classes from the Jetty distribution, 

import org.eclipse.jetty.jaas.JAASRole;

import org.eclipse.jetty.security.UserPrincipal;
import org.eclipse.jetty.util.security.Credential;
I chose to use these three classes, to simplify the process. No need to 
re-invent the wheel with these since they existed already and the 
JDBCLoginModule used them.  Probably the most critical I wanted to use was 
Credential since it provides the password hashing and verification logic. I saw 
no reason to create my own version of this since what I created would pretty 
much be exactly the logic from this. 
I am working with Jetty 11.0.7 and I have the whole thing working fine running 
under eclipse, but when I try and use it in a standalone jetty instance I am 
getting class loader problems. When I try and create a credential using,

Credential.getCredential(neo4jCredential);

I am getting this;

java.lang.NoClassDefFoundError: org/eclipse/jetty/util/security/Credential

When I debug the problem, what I am finding is that the class loader context 
for the JDBCLoginModule is not the same as for my custom login module. When in 
the initialize() method of the login modules I see this;
Using the JDBCLoginModule

this.getClass()

class org.eclipse.jetty.jaas.spi.JDBCLoginModule




this.getClass().getClassLoader()

startJarLoader@2d3379b4







Using the Neo4jLoginModule
this.getClass()


class com.bb.neo4j_login_module.Neo4jLoginModule




this.getClass().getClassLoader()
WebAppClassLoader{Fermenation}@6bc28a83

My login module is deployed just like any other jetty module, isolated from my 
webapp.  These files are included in my JETTY_BASE directory;

etc/neo4j-authentication.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>



<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" 
"https://www.eclipse.org/jetty/configure_10_0.dtd";>



<Configure id="Server" class="org.eclipse.jetty.server.Server">



    <Call name="addBean">



        <Arg>



            <New class="org.eclipse.jetty.jaas.JAASLoginService">



                <Set name="name">beercalc.realm</Set>



                <Set name="LoginModuleName">beercalc.login.module</Set>



            </New>



        </Arg>



    </Call>


</Configure>



lib/neo4j_login_module-1.0.jar
Jar file containing the classes for the login module. Code is in a public repo 
here; GitHub - scottastanley/neo4j_login_module, if there is anything in the 
implementation that should matter.




modules/neo4j-authentication.mod

[description]



Configures the Neo4J JAAS login module.








[depend]



server



jaas








[lib]



lib/neo4j_login_module-1.0.jar








[xml]



etc/neo4j-authentication.xml








[ini-template]



# --------------------------------------- 



# Module: neo4j-authentication



# Enables the JAAS Login service for authentication against Neo4J. 



# --------------------------------------- 



--module=neo4j-authentication



start.d/neo4j-authentication.ini

# --------------------------------------- 



# Module: neo4j-authentication



# Enables the JAAS Login service for authentication against Neo4J. 



# --------------------------------------- 


--module=neo4j-authentication


I am aware that I am not supposed to be able to use server classes in a webapp. 
So, I am sure this is why the Credential class is not found. But I can not 
figure out why my login module is being loaded in the webapp context. I had 
assumed it would operate under the same class loaded as the JDBCLoginModule. I 
know that I should be able to change the filtering of server classes by the 
class loader in the webapp, although the only concrete example I have found is 
doing it for Jetty 8 and this has changed in Jetty 11. So, have not figured 
that out yet. Although I would rather figure out why the module is using the 
webapp classloader so I do not need to set up customer, more permissive class 
loader configuration.
The really funny thing is I have been using the static method 
Credential.MD5.digest(password) in my actual web application for a long time in 
the logic allowing users to change their password. Not sure how or why this 
ever worked, but I know it did in Jetty 8. I will admit, I just tested tonight 
and this no longer works. Must have gotten broken when I upgraded to Jetty 11 
and I never realized.
Is there any way to get my module to utilize the startJarLoader instead of the 
one in the webapp? I would really like to get this figured out. I may need to 
reimplement the whole Credential logic anyway since I can't use the method to 
digest passwords anymore. That would be a shame, but I do need the symmetric 
digest/validate logic available.
I really appreciate any insight anyone has on why the module is using the 
webapp class loader.  Would really like to understand this.  Also, if anyone 
has any suggestions on how to solve this problem besides 
re-implementing/duplicating the credential logic I'd appreciate it.
Scott

 _______________________________________________
jetty-users mailing list
jetty-users@eclipse.org
To unsubscribe from this list, visit 
https://www.eclipse.org/mailman/listinfo/jetty-users



-- 
Jan Bartel <j...@webtide.com>
www.webtide.com
Expert assistance from the creators of Jetty and CometD
  
_______________________________________________
jetty-users mailing list
jetty-users@eclipse.org
To unsubscribe from this list, visit 
https://www.eclipse.org/mailman/listinfo/jetty-users

Reply via email to