How do I bind my LDAPLoginModule to the Jetty paths I define? - ldap

The bounty expires in 3 days. Answers to this question are eligible for a +50 reputation bounty.
Pouissante is looking for an answer from a reputable source.
I am looking for a way to restrict access points to people and/or groups that come from my Active directory. I have managed to configure my ldap-module correctly (I hope) by dropping a ldap-module.xml file in my "deploy" directory in my Apache Karaf containing this (don't mind the DC and CN, they are made up):
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:jaas="http://karaf.apache.org/xmlns/jaas/v1.0.0"
xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0">
<jaas:config name="karaf" rank="1">
<jaas:module className="org.apache.karaf.jaas.modules.ldap.LDAPLoginModule"
flags="required">
connection.url = ldaps://xxxx.com
connection.username=CN=admin,OU=Users, DC=apache,DC=org
connection.password=pass
user.base.dn =OU=Users,DC=apache,DC=org
user.filter = (sAMAccountName=%u)
role.base.dn = OU=Groups,DC=apache,DC=org
role.filter = (memberOf:=sAMAccountName=%u)
role.name.attribute = cn
ssl.protocol=SSL
ssl.algorithm=PKIX
ssl.truststore=ks
authentication = simple
</jaas:module>
</jaas:config>
<jaas:keystore name="ks" path="file:///path/truststore.jks" keystorePassword="pass"/>
I can now see it in my karaf console when doing "jaas:realm-list". It overrides the other login modules, that means I have this one only. Not sure why it does this since I've read on a forum that it should be at rank 100+ to override the standard login modules. It doesn't bother me much since I want to login via LDAP anyway.
Now, when I'm going on a path that is registered with my HttpService, I'm not prompted for credentials, or blocked. I just see everything normally and there is no log in the console. This is a snippet of the servlet:
#Component(name = "xxx-yyy-component", immediate = true)
#WebServlet(name = "xxx yyy Servlet", urlPatterns = { "/xxx-yyy"})
#Activate
public void activate() throws Exception {
httpService.registerServlet("/xxx-yyy", new ImageyyyServlet(), null, null);
}
So in this case, going on https://localhost:8443/xxx-yyy.... displays without restrictions. I then tried to modify my "org.ops4j.pax.web.cfg" file to set the connector with : org.ops4j.pax.web.config.file = ${karaf.etc}/jetty.xml and then in jetty.xml:
<Call name="addBean">
<Arg>
<New class="org.eclipse.jetty.jaas.JAASLoginService">
<Set name="name">karaf</Set>
<Set name="loginModuleName">org.apache.karaf.jaas.modules.ldap.LDAPLoginModule</Set>
<Set name="roleClassNames">
<Array type="java.lang.String">
<Item>org.apache.karaf.jaas.boot.principal.RolePrincipal</Item>
</Array>
</Set>
</New>
</Arg>
</Call>
This didn't work either. I think that even if it worked, it wouldn't restrict selected paths but everything.
I am now clueless on how to proceed.
Every hint appreciated, thanks and best regards

Related

Nuxeo: after activating the Anonymous User can't log in

My goal is to add the anonymous authentication to Nuxeo web ui.
I followed the steps on https://doc.nuxeo.com/nxdoc/how-to-define-public-pages-viewable-by-anonymous-users/.
Created anonymous-auth-config.xml with the following content:
<component name="org.nuxeo.ecm.platform.login.anonymous.config">
<!-- Add an Anonymous user -->
<extension target="org.nuxeo.ecm.platform.usermanager.UserService"
point="userManager">
<userManager>
<users>
<anonymousUser id="Guest">
<property name="firstName">Guest</property>
<property name="lastName">User</property>
</anonymousUser>
</users>
</userManager>
</extension>
</component>
First I copied the file into the C:\Nuxeo\nxserver\config then try folder C:\Nuxeo\templates\common\config.
Modified nuxeo.conf and set nuxeo.user.anonymous.enable=true.
Restart the application server.
Now I can only enter the web ui as Anonymous user, but can't log in as Administrator or any other valid user.
There is forceAnonymousLogin=true query string in the url now by default.
I'm not sure should I change and how the authenticationChain as stated in another link: https://doc.nuxeo.com/nxdoc/using-anonymous-authentication/
Thanks for your help in advance!

How to configure jetty to request client certificate for specified resources?

sslConfig:
<New id="sslContextFactory" class="org.eclipse.jetty.util.ssl.SslContextFactory">
<Set name="KeyStorePath">../conf/jetty/etc/keystore</Set>
<Set name="KeyStorePassword">secretpass</Set>
<Set name="KeyManagerPassword">test</Set>
<Set name="TrustStorePath">../conf/jetty/etc/truststore</Set>
<Set name="TrustStorePassword">secretpass</Set>
<Set name="EndpointIdentificationAlgorithm"></Set>
<Set name="NeedClientAuth">true</Set>
<Set name="WantClientAuth">true</Set>
</New>
Setting NeedClientAuth to true requires client to provide certificate for all resources. But in my case I want to request certificate only for specified resources.
For example I need to request certificate for /resource1/*
And use just HTTPS for /resource2/*
How can I achieve this?
Not possible, as the SSL/TLS negotiation step occurs way before the request is actually made.
No web server can apply different SSL/TLS rules based on the resource being requested, as the information present in the http request hasn't even been sent yet at the time of the SSL/TLS negotiation.
If this is important, set up 2 different ServerConnectors, on different ports.
ServerConnector with Client Auth - the /resource1/* content is served from here
ServerConnector without Client Auth - all other web resources that don't need the client auth requirement (and doesn't even have the /resource1/* content)

org.apache.commons.dbcp.SQLNestedException on tomcat7

I've been fighting with my tomcat server for a while now and it still doesn't work.
I'm using tomcat7, on Debian Wheezy, with PostgreSQL v9.1.
I tried everything possible, and here is what I'm keeping on getting :
database.DataBaseException: Database error while trying to get a new connection. Error information: org.apache.commons.dbcp.SQLNestedException: Cannot create JDBC driver of class '' for connect URL 'null'
database.Connection$.getConnection(Connection.scala:20)
database.Users$.createRegisteredUser(Users.scala:58)
controllers.page.CreateAccountController.before(CreateAccountController.scala:36)
controllers.page.AbstractPageController.processRequest(AbstractPageController.scala:52)
controllers.page.AbstractPageController.doPost(AbstractPageController.scala:79)
javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
I have access to the application pages when I'm running my application and my tomcat server, so far I configured tomcat well enough for this, but as soon as I'm having an action that involves a request to the database (creation of user, etc.), I get this error !
As for the general context of the web application, I've started helping on an already existing project, I installed tomcat7 and cloned the source on my laptop. It works well with the other people working on it - and I haven't made any change to the application code so far (the code works fine): so the error definitely comes from my tomcat configuration and not from the code.
To configure a Tomcat7 server for a web application, what we have to do to configure is creating a context.xml in the META-INF/ directory right ?
I've also added a for the data source to the WEB-INF/web.xml file but it doesn't seem to be mandatory to have a tomcat7 application data source work fine.
I've copied and past my META-INF/context.xml file to Catalina/localhost/ directory with .xml.
I've added the postgres jdbc jar to /usr/share/tomcat7/lib (I've seen a lot of forum posts talking about a conf/lib but I can't find it so I figured it's this lib)
I've read things about tweaking with the tomcat context.xml file and whatnot, but there are pros and cons, and anyway it doesn't work either for me.
Here is my context.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<Resource name="jdbc/dbname"
auth="Container"
type="javax.sql.DataSource"
username="user1"
password="user1"
driverClassName="org.postgresql.Driver"
url="jdbc:postgresql://localhost:5432/dbname"
maxActive="8"
maxIdle="4"/>
<Environment name="encryptionKey" type="java.lang.String" value="<the key>" override="false"/>
</Context>
What I added to the WEB-INF/web.xml:
<resource-ref>
<res-ref-name>jdbc/dbname</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
The code sample where it all starts (application written in scala) :
private val ds: DataSource = new javax.naming.InitialContext().lookup("java:comp/env/jdbc/dbname").asInstanceOf[DataSource]
private var connec: java.sql.Connection = null
def getConnection(): java.sql.Connection = {
try {
if (connec == null) {
connec = ds.getConnection() //here is raised the error
connec.setAutoCommit(false)
}
connec
} catch {
case ex: SQLException => throw new DataBaseException("Database error while trying to get a new connection. Error information: " + ex.toString())
}
}
I tried to run the application without context.xml and without the copy of if in the Catalina/localhost directory, and I get the same error. I guess the server just doesn't find my context.xml file ?
The last thing is I've compared my context.xml with some other people from the project, and they have exactly the same - and it works for them (except the db name and password that depends on what they chose)....
I also made sure the port 5432 is the right one, and it is.
Yes, it's pretty puzzly !
If you want more precision (I might be missing relevant things) don't hesitate to ask me !

Enabling authentication realm in jetty 8

I tried to follow the offical tutorial to enable MD5 authentication for my only web-app running on jetty. Nginx manages ssl and redirects to jetty
I placed
<Call name="addBean">
<Arg>
<New class="org.eclipse.jetty.security.HashLoginService">
<Set name="name">My Realm</Set>
<Set name="config"><SystemProperty name="jetty.home" default="."/>/etc/realm.properties</Set>
<Set name="refreshInterval">0</Set>
</New>
</Arg>
</Call>
In jetty.xml, and the content of realm.properties are :
test: MD5:098f6bcd4621d373cade4e832627b4f6,user
In the tutorial they do not tell where to assign the realm to a context so I don't know where to place this :
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
<Get name="securityHandler">
<Set name="realmName">My Realm</Set>
</Get>
</Configure>
I tried to put in in jetty-context.xml, and in web.xml, but it is still not working. I receive a 502 (bad gateway) when I place this in jetty.xml, in the other cases I get a normal json result from the web service (Shouldn't I get a 503 - not authorized ?)
A "Context XML File" (as outlined in Configuring Security Realms) refers Webapp deployment using the ContextProvider (enabled by default on jetty-distribution).
This deploys webapps by using a XML file, usually found in ${jetty.home}/contexts/ with a description of where that webapp is located on disk, and some details on how you want that webapp deployed.
You can also use the WEB-INF/jetty-web.xml to embed this Context configuration within your WAR file.

View content of H2 or HSQLDB in-memory database

Is there a way to browse the content of an H2 or an HSQLDB in-memory database for viewing? For example, during a debugging session with Hibernate in order to check when the flush is executed; or to make sure the script that instantiates the DB gives the expected result.
Does it exist an addon or a library that you can embed with your code in order to allow this?
Please, mention which one you're talking about (H2 or HSQLDB) in case you have an answer specific to one of them.
You can run H2 web server within your application that will access the same in-memory database. You can also access the H2 running in server mode using any generic JDBC client like SquirrelSQL.
UPDATE:
Server webServer = Server.createWebServer("-web,-webAllowOthers,true,-webPort,8082").start();
Server server = Server.createTcpServer("-tcp,-tcpAllowOthers,true,-tcpPort,9092").start();
Now you can connect to your database via jdbc:h2:mem:foo_db URL within the same process or browse the foo_db database using localhost:8082. Remember to close both servers. See also: H2 database in memory mode cannot be accessed by Console.
You can also use Spring:
<bean id="h2Server" class="org.h2.tools.Server" factory-method="createTcpServer" init-method="start" destroy-method="stop" depends-on="h2WebServer">
<constructor-arg value="-tcp,-tcpAllowOthers,true,-tcpPort,9092"/>
</bean>
<bean id="h2WebServer" class="org.h2.tools.Server" factory-method="createWebServer" init-method="start" destroy-method="stop">
<constructor-arg value="-web,-webAllowOthers,true,-webPort,8082"/>
</bean>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close" depends-on="h2Server">
<property name="driverClass" value="org.h2.Driver"/>
<property name="jdbcUrl" value="jdbc:h2:mem:foo_db"/>
</bean>
BTW you should only depend on assertions and not on manual peeking the database contents. Use this only for troubleshooting.
N.B. if you use Spring test framework you won't see changes made by a running transaction and this transaction will be rolled back immediately after the test.
For H2, you can start a web server within your code during a debugging session if you have a database connection object. You could add this line to your code, or as a 'watch expression' (dynamically):
org.h2.tools.Server.startWebServer(conn);
The server tool will start a web browser locally that allows you to access the database.
In H2, what works for me is:
I code, starting the server like:
server = Server.createTcpServer().start();
That starts the server on localhost port 9092.
Then, in code, establish a DB connection on the following JDBC URL:
jdbc:h2:tcp://localhost:9092/mem:test;DB_CLOSE_DELAY=-1;MODE=MySQL
While debugging, as a client to inspect the DB I use the one provided by H2, which is good enough, to launch it you just need to launch the following java main separately
org.h2.tools.Console
This will start a web server with an app on 8082, launch a browser on localhost:8082
And then you can enter the previous URL to see the DB
With HSQLDB, you have several built-in options.
There are two GUI database managers and a command line interface to the database. The classes for these are:
org.hsqldb.util.DatabaseManager
org.hsqldb.util.DatabaseManagerSwing
org.hsqldb.cmdline.SqlTool
You can start one of the above from your application and access the in-memory databases.
An example with JBoss is given here:
http://docs.jboss.org/jbpm/v3.2/userguide/html/ch07s03.html
You can also start a server with your application, pointing it to an in-memory database.
org.hsqldb.Server
For HSQLDB, The following worked for me:
DatabaseManager.threadedDBM();
And this brought up the GUI with my tables and data once I pointed it to the right named in-mem database.
It is basically the equivalent of newing up a DatabaseManager (the non Swing variety), which prompts for connection details, and is set to --noexit)
I also tried the Swing version, but it only had a main, and I was unsure of the arguments to pass. If anyone knows, please post here.
Just because I searched for hours for the right database name: The name of the database is the name of your datasource. So try with URL jdbc:hsqldb:mem:dataSource if you have a data source bean with id=dataSource. If this does not work, try testdb which is the default.
You can expose it as a JMX feature, startable via JConsole:
#ManagedResource
#Named
public class DbManager {
#ManagedOperation(description = "Start HSQL DatabaseManagerSwing.")
public void dbManager() {
String[] args = {"--url", "jdbc:hsqldb:mem:embeddedDataSource", "--noexit"};
DatabaseManagerSwing.main(args);
}
}
XML context:
<context:component-scan base-package="your.package.root" scoped-proxy="targetClass"/>
<context:annotation-config />
<context:mbean-server />
<context:mbean-export />
This is a Play 2 controller to initialize the H2 TCP and Web servers:
package controllers;
import org.h2.tools.Server;
import play.mvc.Controller;
import play.mvc.Result;
import java.sql.SQLException;
/**
* Play 2 controller to initialize H2 TCP Server and H2 Web Console Server.
*
* Once it's initialized, you can connect with a JDBC client with
* the URL `jdbc:h2:tcp://127.0.1.1:9092/mem:DBNAME`,
* or can be accessed with the web console at `http://localhost:8082`,
* and the URL JDBC `jdbc:h2:mem:DBNAME`.
*
* #author Mariano Ruiz <mrsarm#gmail.com>
*/
public class H2ServerController extends Controller {
private static Server h2Server = null;
private static Server h2WebServer = null;
public static synchronized Result debugH2() throws SQLException {
if (h2Server == null) {
h2Server = Server.createTcpServer("-tcp", "-tcpAllowOthers", "-tcpPort", "9092");
h2Server.start();
h2WebServer = Server.createWebServer("-web","-webAllowOthers","-webPort","8082");
h2WebServer.start();
return ok("H2 TCP/Web servers initialized");
} else {
return ok("H2 TCP/Web servers already initialized");
}
}
}
I've a problem with H2 version 1.4.190 remote connection to inMemory (as well as in file) with Connection is broken: "unexpected status 16843008" until do not downgrade to 1.3.176. See Grails accessing H2 TCP server hangs
This is more a comment to previous Thomas Mueller's post rather than an answer, but haven't got enough reputation for it. Another way of getting the connection if you are Spring JDBC Template is using the following:
jdbcTemplate.getDataSource().getConnection();
So on debug mode if you add to the "Expressions" view in Eclipse it will open the browser showing you the H2 Console:
org.h2.tools.Server.startWebServer(jdbcTemplate.getDataSource().getConnection());
Eclipse Expressions View
H2 Console
I don't know why is it working fine at yours machines, but I had to spend a day in order to get it is working.
The server works with Intellij Idea U via url "jdbc:h2:tcp://localhost:9092/~/default".
"localhost:8082" in the browser alse works fine.
I added this into the mvc-dispatcher-servlet.xml
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" depends-on="h2Server">
<property name="driverClassName" value="org.h2.Driver"/>
<property name="url" value="jdbc:h2:tcp://localhost:9092/~/default"/>
<property name="username" value="sa"/>
<property name="password" value=""/>
</bean>
<bean id="h2Server" class="org.h2.tools.Server" factory-method="createTcpServer" init-method="start" destroy-method="stop" depends-on="h2WebServer">
<constructor-arg>
<array>
<value>-tcp</value>
<value>-tcpAllowOthers</value>
<value>-tcpPort</value>
<value>9092</value>
</array>
</constructor-arg>
</bean>
<bean id="h2WebServer" class="org.h2.tools.Server" factory-method="createWebServer" init-method="start" destroy-method="stop">
<constructor-arg>
<array>
<value>-web</value>
<value>-webAllowOthers</value>
<value>-webPort</value>
<value>8082</value>
</array>
</constructor-arg>
</bean>
What about comfortably viewing (and also editing) the content over ODBC & MS-Access, Excel?
Softwareversions::
H2 Version:1.4.196
Win 10 Postgres ODBC Driver Version: psqlodbc_09_03_0210
For Win7 ODBC Client: win7_psqlodbc_09_00_0101-x64.msi
H2 Server:
/*
For JDBC Clients to connect:
jdbc:h2:tcp://localhost:9092/trader;CIPHER=AES;IFEXISTS=TRUE;MVCC=true;LOCK_TIMEOUT=60000;CACHE_SIZE=131072;CACHE_TYPE=TQ
*/
public class DBStarter {
public static final String BASEDIR = "/C:/Trader/db/";
public static final String DB_URL = BASEDIR + "trader;CIPHER=AES;IFEXISTS=TRUE;MVCC=true;LOCK_TIMEOUT=10000;CACHE_SIZE=131072;CACHE_TYPE=TQ";
static void startServer() throws SQLException {
Server tcpServer = Server.createTcpServer(
"-tcpPort", "9092",
"-tcpAllowOthers",
"-ifExists",
// "-trace",
"-baseDir", BASEDIR
);
tcpServer.start();
System.out.println("H2 JDBC Server started: " + tcpServer.getStatus());
Server pgServer = Server.createPgServer(
"-pgPort", "10022",
"-pgAllowOthers",
"-key", "traderdb", DB_URL
);
pgServer.start();
System.out.println("H2 ODBC PGServer started: " + pgServer.getStatus());
}
}
Windows10 ODBC Datasource Configuration which can be used by any ODBC client:
In Databse field the name given in '-key' parameter has to be used.