You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@karaf.apache.org by Markus Rathgeb <ma...@gmail.com> on 2019/05/16 06:12:43 UTC

Karaf, Pax Web, Jetty: "some" client authentication

Hi,

I assume there are different parties involved, so if this question
should be raised on another mailing list, please can you point me to?

I am using Karaf + Pax Web + Jetty.

Currently I build a custom distribution that Pax Web configuration
(org.ops4j.pax.web.cfg) contains also this lines:

===
org.ops4j.pax.web.ssl.clientauthwanted = true
org.ops4j.pax.web.ssl.clientauthneeded = true

org.ops4j.pax.web.ssl.truststore=${karaf.etc}/truststore.jks
org.ops4j.pax.web.ssl.truststore.password=that-is-not-the-real-one
===

This distribution contains a bundle that registers a servlet "MyServlet".

Now, just FYI, I assume not all is relevant:

===
"MyServlet" extends the "WebSocketServlet"
(org.eclipse.jetty.websocket.servlet.WebSocketServlet).
Type hierarchy: MyServlet -> WebSocketServlet -> HttpServlet ->
GenericServlet [Servlet, ServletConfig, Serializable].

The WebSocketServlet requires the implementation of the abstract
method "public abstract void configure(WebSocketServletFactory
factory);"

In the "configure" implementation is set a "creator".

factory.setCreator(new MyCreator(...));

MyCreator implements the following method (required by the
WebSocketCreator interface):

public @Nullable Object createWebSocket(final ServletUpgradeRequest
req, final ServletUpgradeResponse resp);

In that method I do a simple certificate check.

I call "final X509Certificate[] certs = req.getCertificates();" and
use the returned chain for the check.

Now back to the relevant part.
===

The current implementation of the client certificate chain check
relies that Jetty already required the client authentication
(clientauthneeded) and that the certificate is already checked against
the configured truststore (that contains only a special CA).

As we could rely on a "valid" certifcate I just need to extract the
information I need from the client certifcate and "all is fine".


Now, I need to add another servlet to that custom distribution that
should work without a client certifcate.

I assume I will need to remove the truststore and clientauth settings
from the configuration (keep wanted and drop needed?) and check the
certifcate in the code for "MyServlet" itself.
I further assume it should work by a filter or in the servlet itself.

Are there better ways to handle two servlet
* Servlet1 needs client authentication
* Servlet2 do not use client authentication

How can I trigger the check of the client certificate correctly in the
servlet / filter to check against a specific truststore?

I am interested in your inputs.

Best regards,
Markus

Re: Karaf, Pax Web, Jetty: "some" client authentication

Posted by Steinar Bang <sb...@dod.no>.
>>>>> Markus Rathgeb <ma...@gmail.com>:

> I assume I need to use a "Web Application" and cannot rely on servlets etc.
> https://osgi.org/specification/osgi.cmpn/7.0.0/service.war.html

> Any change to get this mixed with Declarative Service?

This is how I make webapps with apache karaf:
 1. Define a service interface for the webapp, including the beans that
    will define the REST API wire format
    Examples:
     https://github.com/steinarb/ukelonn/blob/master/ukelonn.services/src/main/java/no/priv/bang/ukelonn/UkelonnService.java#L40
     https://github.com/steinarb/handlereg/blob/master/handlereg.services/src/main/java/no/priv/bang/handlereg/services/HandleregService.java#L20
 2. Define an application specific database interface (for easy
    avoidance of "application interference with DS service injection" 
    Examples:
     https://github.com/steinarb/ukelonn/blob/master/ukelonn.services/src/main/java/no/priv/bang/ukelonn/UkelonnDatabase.java#L20
     https://github.com/steinarb/authservice/blob/master/authservice.definitions/src/main/java/no/priv/bang/authservice/definitions/AuthserviceDatabaseService.java#L30
     https://github.com/steinarb/handlereg/blob/master/handlereg.services/src/main/java/no/priv/bang/handlereg/services/HandleregDatabase.java#L21
 3. Define a liquibase schema definition for the database
    Examples:
     https://github.com/steinarb/ukelonn/tree/master/ukelonn.db.liquibase/src/main/resources/ukelonn-db-changelog
     https://github.com/steinarb/authservice/tree/master/authservice.db.liquibase/src/main/resources/authservice-db-changelog
     https://github.com/steinarb/handlereg/tree/master/handlereg.db.liquibase/src/main/resources/handlereg-db-changelog
 4. Define a DS component that exposes the application specific database
    interface for a derby database, and runs the liquibase schema in its
    activate method (and also adds some dummy data using liquibase)
    Examples:
     https://github.com/steinarb/ukelonn/blob/master/ukelonn.db.derbytest/src/main/java/no/priv/bang/ukelonn/db/derbytest/UkelonnDatabaseProvider.java#L47
     https://github.com/steinarb/authservice/blob/master/authservice.db.derby.test/src/main/java/no/priv/bang/authservice/db/derby/test/DerbyTestDatabase.java#L34
     https://github.com/steinarb/handlereg/blob/master/handlereg.db.derby.test/src/main/java/no/priv/bang/handlereg/db/derby/test/HandleregDerbyTestDatabase.java#L40
 5. Create a DS component implementing the service interface, using a
    derby database in the unit tests
    Examples:
     https://github.com/steinarb/ukelonn/blob/master/ukelonn.backend/src/main/java/no/priv/bang/ukelonn/backend/UkelonnServiceProvider.java#L58
     https://github.com/steinarb/handlereg/blob/master/handlereg.backend/src/main/java/no/priv/bang/handlereg/backend/HandleregServiceProvider.java#L44
 6. Create a DS component adding a web context (ie. the prefix of your
    application, eg. "/authservice" in "http://localhost:8181/authservice")
    to the web whiteboard, and another DS component adding a  shiro
    filter to the web whiteboard, using authservice to provide the Realm
    and SessionDAO (injected as OSGi services into the filter
    component).  Not much actual code, but pulls in a lot of runtime
    stuff
    Examples of contexts and filters:
     https://github.com/steinarb/ukelonn/blob/master/ukelonn.web.security/src/main/java/no/priv/bang/ukelonn/web/security/UkelonnServletContextHelper.java#L7
     https://github.com/steinarb/ukelonn/blob/master/ukelonn.web.security/src/main/java/no/priv/bang/ukelonn/web/security/UkelonnShiroFilter.java#L41
     https://github.com/steinarb/authservice/blob/master/authservice.web.security/src/main/java/no/priv/bang/authservice/web/security/AuthserviceServletContextHelper.java#L22
     https://github.com/steinarb/authservice/blob/master/authservice.web.security/src/main/java/no/priv/bang/authservice/web/security/AuthserviceShiroFilter.java#L44
     https://github.com/steinarb/handlereg/blob/master/handlereg.web.security/src/main/java/no/priv/bang/handlereg/web/security/HandleregServletContextHelper.java#L22
     https://github.com/steinarb/handlereg/blob/master/handlereg.web.security/src/main/java/no/priv/bang/handlereg/web/security/HandleregShiroFilter.java#L38
 7. Create a DS component adding the rest API to the web context in the
    web whiteboard, accepting the service interface as an OSGi
    injection, and injecting it into the jersey  resources that serves
    the requests.  In the tests of the REST endpoints I use mocks for
    the service interface, so this component doesn't need jersey for its
    tests
    Examples:
     https://github.com/steinarb/ukelonn/blob/master/ukelonn.web.services/src/main/java/no/priv/bang/ukelonn/api/UkelonnRestApiServlet.java#L38
     https://github.com/steinarb/handlereg/blob/master/handlereg.web.api/src/main/java/no/priv/bang/handlereg/web/api/HandleregWebApi.java#L38
 8. Create a DS component adding a react frontend to the web context
    Examples:
     https://github.com/steinarb/ukelonn/blob/master/ukelonn.web.frontend/src/main/java/no/priv/bang/ukelonn/web/frontend/UkelonnServlet.java#L36
     https://github.com/steinarb/handlereg/blob/master/handlereg.web.frontend/src/main/java/no/priv/bang/handlereg/web/frontend/HandleregServlet.java#L36
 9. Create a karaf feature loading the web application with a derby
    database and with authservice to provide the user management
    Examples
     https://github.com/steinarb/ukelonn/blob/master/karaf/src/main/filtered-resources/feature.xml#L32
     https://github.com/steinarb/handlereg/blob/master/src/main/filtered-resources/feature.xml#L25

At this point the application can be started and tested on an apache
karaf instance.

The next step is to create a PostgreSQL database similar to th ederby
database, but more permanent.


Re: Karaf, Pax Web, Jetty: "some" client authentication

Posted by Achim Nierbeck <bc...@googlemail.com>.
Right now this only works for webbundles as their web-context is bound to a
connector.
Haven't tried it, but it could be bend to work with whiteboard servlets.

regards, Achim

Am Do., 16. Mai 2019 um 21:23 Uhr schrieb Markus Rathgeb <
maggu2810@gmail.com>:

> I assume I need to use a "Web Application" and cannot rely on servlets etc.
> https://osgi.org/specification/osgi.cmpn/7.0.0/service.war.html
>
> Any change to get this mixed with Declarative Service?
>
> Am Do., 16. Mai 2019 um 20:32 Uhr schrieb Markus Rathgeb <
> maggu2810@gmail.com>:
> >
> > If this already known (WRT to the following comment)?
> >
> https://nierbeck.de/2013/01/bind-certain-web-applications-to-specific-httpconnectors/#comment-62
> >
> > Am Do., 16. Mai 2019 um 20:26 Uhr schrieb Markus Rathgeb <
> maggu2810@gmail.com>:
> > >
> > > Hi Łukasz, hi JB,
> > >
> > > thank you for that information.
> > >
> > > I did not found an official documentation for that feature.
> > >
> > > I found this one (WRT the information given to me from you):
> > > * https://ops4j1.jira.com/browse/PAXWEB-396
> > > *
> https://nierbeck.de/2013/01/bind-certain-web-applications-to-specific-httpconnectors/
> > > * http://blog.nanthrax.net/?p=352
> > > * Source code of Pax Web
> > >
> > > I gave it a try using two additional connectors in jetty.xml.
> > > I used the example that has been present in the current jetty.xml as
> > > "SelectChannelConnector" did not work ("Caused by:
> > > java.lang.ClassNotFoundException:
> > > org.eclipse.jetty.server.nio.SelectChannelConnector not found by
> > > org.eclipse.jetty.server [62]").
> > > ===
> > >     <Call name="addConnector">
> > >         <Arg>
> > >             <New class="org.eclipse.jetty.server.ServerConnector">
> > >                 <Arg name="server"><Ref refid="Server" /></Arg>
> > >                 <Arg name="factories">
> > >                     <Array
> type="org.eclipse.jetty.server.ConnectionFactory">
> > >                         <Item>
> > >                             <New
> > > class="org.eclipse.jetty.server.HttpConnectionFactory">
> > >                                 <Arg name="config"><Ref
> > > refid="httpConfig" /></Arg>
> > >                             </New>
> > >                         </Item>
> > >                     </Array>
> > >                 </Arg>
> > >                 <Set name="host"><Property name="jetty.host"
> > > default="localhost" /></Set>
> > >                 <Set name="port"><Property name="jetty.port"
> > > default="8201" /></Set>
> > >                 <Set name="idleTimeout"><Property name="http.timeout"
> > > default="30000" /></Set>
> > >                 <Set name="name">conn1</Set>
> > >             </New>
> > >         </Arg>
> > >     </Call>
> > >     <Call name="addConnector">
> > >         <Arg>
> > >             <New class="org.eclipse.jetty.server.ServerConnector">
> > >                 <Arg name="server"><Ref refid="Server" /></Arg>
> > >                 <Arg name="factories">
> > >                     <Array
> type="org.eclipse.jetty.server.ConnectionFactory">
> > >                         <Item>
> > >                             <New
> > > class="org.eclipse.jetty.server.HttpConnectionFactory">
> > >                                 <Arg name="config"><Ref
> > > refid="httpConfig" /></Arg>
> > >                             </New>
> > >                         </Item>
> > >                     </Array>
> > >                 </Arg>
> > >                 <Set name="host"><Property name="jetty.host"
> > > default="localhost" /></Set>
> > >                 <Set name="port"><Property name="jetty.port"
> > > default="8202" /></Set>
> > >                 <Set name="idleTimeout"><Property name="http.timeout"
> > > default="30000" /></Set>
> > >                 <Set name="name">conn2</Set>
> > >             </New>
> > >         </Arg>
> > >     </Call>
> > > ===
> > >
> > > So, additional to 8181 there should be two connetors. conn1 on 8201
> > > and conn2 on 8202.
> > >
> > > I created two bundles. Each bundle registers one servlet and use one
> > > Web-Connector settings:
> > >
> > > Bundle 1 - Component:
> > > ===
> > > @Component(immediate = true)
> > > @Header(name = "Web-Connectors", value = "conn1")
> > > @Header(name = "Web-VirtualHosts", value = "localhost")
> > > public class ComponentImpl {
> > >
> > >     private static final String ALIAS = "/1";
> > >
> > >     private final HttpService httpService;
> > >
> > >     @Activate
> > >     public ComponentImpl(final @Reference HttpService httpService)
> > > throws ServletException, NamespaceException {
> > >         this.httpService = httpService;
> > >         httpService.registerServlet(ALIAS, new HttpServlet() {
> > >
> > >             @Override
> > >             protected void doGet(final HttpServletRequest req, final
> > > HttpServletResponse resp)
> > >                     throws ServletException, IOException {
> > >                 final PrintWriter writer = resp.getWriter();
> > >                 writer.println("This is the servlet: " + ALIAS);
> > >             }
> > >
> > >         }, null, null);
> > >     }
> > >
> > >     @Deactivate
> > >     public void close() {
> > >         httpService.unregister(ALIAS);
> > >     }
> > >
> > > }
> > > ===
> > >
> > > The "Bundle 2 - Component" is identicial to the "1" but uses the alias
> > > "/2" and the "Web-Connectors" "conn2".
> > >
> > > But this does not seem to work as expected.
> > > "/1" and "/2" can be open on port 8181, 8201 and 8202.
> > >
> > > So, all of them are available on all connectors.
> > >
> > > Can you point me to my misconfiguration?
> > > Or can you provide me two working demo bundles each of them using
> > > another connector?
> > >
> > > Best regards,
> > > Markus
> > >
> > > Am Do., 16. Mai 2019 um 16:18 Uhr schrieb Jean-Baptiste Onofré
> > > <jb...@nanthrax.net>:
> > > >
> > > > Hi,
> > > >
> > > > I'm not sure it's what you are looking for, but you can configure
> > > > several connectors via jetty.xml (in addition of the default one
> created
> > > > by Pax Web), then, you can use "VirtualHost" to deploy a servlet on a
> > > > specific connector.
> > > >
> > > > I blogged about this while ago (http://blog.nanthrax.net/?p=352).
> > > >
> > > > Regards
> > > > JB
> > > >
> > > > On 16/05/2019 08:12, Markus Rathgeb wrote:
> > > > > Hi,
> > > > >
> > > > > I assume there are different parties involved, so if this question
> > > > > should be raised on another mailing list, please can you point me
> to?
> > > > >
> > > > > I am using Karaf + Pax Web + Jetty.
> > > > >
> > > > > Currently I build a custom distribution that Pax Web configuration
> > > > > (org.ops4j.pax.web.cfg) contains also this lines:
> > > > >
> > > > > ===
> > > > > org.ops4j.pax.web.ssl.clientauthwanted = true
> > > > > org.ops4j.pax.web.ssl.clientauthneeded = true
> > > > >
> > > > > org.ops4j.pax.web.ssl.truststore=${karaf.etc}/truststore.jks
> > > > > org.ops4j.pax.web.ssl.truststore.password=that-is-not-the-real-one
> > > > > ===
> > > > >
> > > > > This distribution contains a bundle that registers a servlet
> "MyServlet".
> > > > >
> > > > > Now, just FYI, I assume not all is relevant:
> > > > >
> > > > > ===
> > > > > "MyServlet" extends the "WebSocketServlet"
> > > > > (org.eclipse.jetty.websocket.servlet.WebSocketServlet).
> > > > > Type hierarchy: MyServlet -> WebSocketServlet -> HttpServlet ->
> > > > > GenericServlet [Servlet, ServletConfig, Serializable].
> > > > >
> > > > > The WebSocketServlet requires the implementation of the abstract
> > > > > method "public abstract void configure(WebSocketServletFactory
> > > > > factory);"
> > > > >
> > > > > In the "configure" implementation is set a "creator".
> > > > >
> > > > > factory.setCreator(new MyCreator(...));
> > > > >
> > > > > MyCreator implements the following method (required by the
> > > > > WebSocketCreator interface):
> > > > >
> > > > > public @Nullable Object createWebSocket(final ServletUpgradeRequest
> > > > > req, final ServletUpgradeResponse resp);
> > > > >
> > > > > In that method I do a simple certificate check.
> > > > >
> > > > > I call "final X509Certificate[] certs = req.getCertificates();" and
> > > > > use the returned chain for the check.
> > > > >
> > > > > Now back to the relevant part.
> > > > > ===
> > > > >
> > > > > The current implementation of the client certificate chain check
> > > > > relies that Jetty already required the client authentication
> > > > > (clientauthneeded) and that the certificate is already checked
> against
> > > > > the configured truststore (that contains only a special CA).
> > > > >
> > > > > As we could rely on a "valid" certifcate I just need to extract the
> > > > > information I need from the client certifcate and "all is fine".
> > > > >
> > > > >
> > > > > Now, I need to add another servlet to that custom distribution that
> > > > > should work without a client certifcate.
> > > > >
> > > > > I assume I will need to remove the truststore and clientauth
> settings
> > > > > from the configuration (keep wanted and drop needed?) and check the
> > > > > certifcate in the code for "MyServlet" itself.
> > > > > I further assume it should work by a filter or in the servlet
> itself.
> > > > >
> > > > > Are there better ways to handle two servlet
> > > > > * Servlet1 needs client authentication
> > > > > * Servlet2 do not use client authentication
> > > > >
> > > > > How can I trigger the check of the client certificate correctly in
> the
> > > > > servlet / filter to check against a specific truststore?
> > > > >
> > > > > I am interested in your inputs.
> > > > >
> > > > > Best regards,
> > > > > Markus
> > > > >
> > > >
> > > > --
> > > > Jean-Baptiste Onofré
> > > > jbonofre@apache.org
> > > > http://blog.nanthrax.net
> > > > Talend - http://www.talend.com
>


-- 

Apache Member
Apache Karaf <http://karaf.apache.org/> Committer & PMC
OPS4J Pax Web <http://wiki.ops4j.org/display/paxweb/Pax+Web/> Committer &
Project Lead
blog <http://notizblog.nierbeck.de/>
Co-Author of Apache Karaf Cookbook <http://bit.ly/1ps9rkS>

Software Architect / Project Manager / Scrum Master

Re: Karaf, Pax Web, Jetty: "some" client authentication

Posted by Markus Rathgeb <ma...@gmail.com>.
I assume I need to use a "Web Application" and cannot rely on servlets etc.
https://osgi.org/specification/osgi.cmpn/7.0.0/service.war.html

Any change to get this mixed with Declarative Service?

Am Do., 16. Mai 2019 um 20:32 Uhr schrieb Markus Rathgeb <ma...@gmail.com>:
>
> If this already known (WRT to the following comment)?
> https://nierbeck.de/2013/01/bind-certain-web-applications-to-specific-httpconnectors/#comment-62
>
> Am Do., 16. Mai 2019 um 20:26 Uhr schrieb Markus Rathgeb <ma...@gmail.com>:
> >
> > Hi Łukasz, hi JB,
> >
> > thank you for that information.
> >
> > I did not found an official documentation for that feature.
> >
> > I found this one (WRT the information given to me from you):
> > * https://ops4j1.jira.com/browse/PAXWEB-396
> > * https://nierbeck.de/2013/01/bind-certain-web-applications-to-specific-httpconnectors/
> > * http://blog.nanthrax.net/?p=352
> > * Source code of Pax Web
> >
> > I gave it a try using two additional connectors in jetty.xml.
> > I used the example that has been present in the current jetty.xml as
> > "SelectChannelConnector" did not work ("Caused by:
> > java.lang.ClassNotFoundException:
> > org.eclipse.jetty.server.nio.SelectChannelConnector not found by
> > org.eclipse.jetty.server [62]").
> > ===
> >     <Call name="addConnector">
> >         <Arg>
> >             <New class="org.eclipse.jetty.server.ServerConnector">
> >                 <Arg name="server"><Ref refid="Server" /></Arg>
> >                 <Arg name="factories">
> >                     <Array type="org.eclipse.jetty.server.ConnectionFactory">
> >                         <Item>
> >                             <New
> > class="org.eclipse.jetty.server.HttpConnectionFactory">
> >                                 <Arg name="config"><Ref
> > refid="httpConfig" /></Arg>
> >                             </New>
> >                         </Item>
> >                     </Array>
> >                 </Arg>
> >                 <Set name="host"><Property name="jetty.host"
> > default="localhost" /></Set>
> >                 <Set name="port"><Property name="jetty.port"
> > default="8201" /></Set>
> >                 <Set name="idleTimeout"><Property name="http.timeout"
> > default="30000" /></Set>
> >                 <Set name="name">conn1</Set>
> >             </New>
> >         </Arg>
> >     </Call>
> >     <Call name="addConnector">
> >         <Arg>
> >             <New class="org.eclipse.jetty.server.ServerConnector">
> >                 <Arg name="server"><Ref refid="Server" /></Arg>
> >                 <Arg name="factories">
> >                     <Array type="org.eclipse.jetty.server.ConnectionFactory">
> >                         <Item>
> >                             <New
> > class="org.eclipse.jetty.server.HttpConnectionFactory">
> >                                 <Arg name="config"><Ref
> > refid="httpConfig" /></Arg>
> >                             </New>
> >                         </Item>
> >                     </Array>
> >                 </Arg>
> >                 <Set name="host"><Property name="jetty.host"
> > default="localhost" /></Set>
> >                 <Set name="port"><Property name="jetty.port"
> > default="8202" /></Set>
> >                 <Set name="idleTimeout"><Property name="http.timeout"
> > default="30000" /></Set>
> >                 <Set name="name">conn2</Set>
> >             </New>
> >         </Arg>
> >     </Call>
> > ===
> >
> > So, additional to 8181 there should be two connetors. conn1 on 8201
> > and conn2 on 8202.
> >
> > I created two bundles. Each bundle registers one servlet and use one
> > Web-Connector settings:
> >
> > Bundle 1 - Component:
> > ===
> > @Component(immediate = true)
> > @Header(name = "Web-Connectors", value = "conn1")
> > @Header(name = "Web-VirtualHosts", value = "localhost")
> > public class ComponentImpl {
> >
> >     private static final String ALIAS = "/1";
> >
> >     private final HttpService httpService;
> >
> >     @Activate
> >     public ComponentImpl(final @Reference HttpService httpService)
> > throws ServletException, NamespaceException {
> >         this.httpService = httpService;
> >         httpService.registerServlet(ALIAS, new HttpServlet() {
> >
> >             @Override
> >             protected void doGet(final HttpServletRequest req, final
> > HttpServletResponse resp)
> >                     throws ServletException, IOException {
> >                 final PrintWriter writer = resp.getWriter();
> >                 writer.println("This is the servlet: " + ALIAS);
> >             }
> >
> >         }, null, null);
> >     }
> >
> >     @Deactivate
> >     public void close() {
> >         httpService.unregister(ALIAS);
> >     }
> >
> > }
> > ===
> >
> > The "Bundle 2 - Component" is identicial to the "1" but uses the alias
> > "/2" and the "Web-Connectors" "conn2".
> >
> > But this does not seem to work as expected.
> > "/1" and "/2" can be open on port 8181, 8201 and 8202.
> >
> > So, all of them are available on all connectors.
> >
> > Can you point me to my misconfiguration?
> > Or can you provide me two working demo bundles each of them using
> > another connector?
> >
> > Best regards,
> > Markus
> >
> > Am Do., 16. Mai 2019 um 16:18 Uhr schrieb Jean-Baptiste Onofré
> > <jb...@nanthrax.net>:
> > >
> > > Hi,
> > >
> > > I'm not sure it's what you are looking for, but you can configure
> > > several connectors via jetty.xml (in addition of the default one created
> > > by Pax Web), then, you can use "VirtualHost" to deploy a servlet on a
> > > specific connector.
> > >
> > > I blogged about this while ago (http://blog.nanthrax.net/?p=352).
> > >
> > > Regards
> > > JB
> > >
> > > On 16/05/2019 08:12, Markus Rathgeb wrote:
> > > > Hi,
> > > >
> > > > I assume there are different parties involved, so if this question
> > > > should be raised on another mailing list, please can you point me to?
> > > >
> > > > I am using Karaf + Pax Web + Jetty.
> > > >
> > > > Currently I build a custom distribution that Pax Web configuration
> > > > (org.ops4j.pax.web.cfg) contains also this lines:
> > > >
> > > > ===
> > > > org.ops4j.pax.web.ssl.clientauthwanted = true
> > > > org.ops4j.pax.web.ssl.clientauthneeded = true
> > > >
> > > > org.ops4j.pax.web.ssl.truststore=${karaf.etc}/truststore.jks
> > > > org.ops4j.pax.web.ssl.truststore.password=that-is-not-the-real-one
> > > > ===
> > > >
> > > > This distribution contains a bundle that registers a servlet "MyServlet".
> > > >
> > > > Now, just FYI, I assume not all is relevant:
> > > >
> > > > ===
> > > > "MyServlet" extends the "WebSocketServlet"
> > > > (org.eclipse.jetty.websocket.servlet.WebSocketServlet).
> > > > Type hierarchy: MyServlet -> WebSocketServlet -> HttpServlet ->
> > > > GenericServlet [Servlet, ServletConfig, Serializable].
> > > >
> > > > The WebSocketServlet requires the implementation of the abstract
> > > > method "public abstract void configure(WebSocketServletFactory
> > > > factory);"
> > > >
> > > > In the "configure" implementation is set a "creator".
> > > >
> > > > factory.setCreator(new MyCreator(...));
> > > >
> > > > MyCreator implements the following method (required by the
> > > > WebSocketCreator interface):
> > > >
> > > > public @Nullable Object createWebSocket(final ServletUpgradeRequest
> > > > req, final ServletUpgradeResponse resp);
> > > >
> > > > In that method I do a simple certificate check.
> > > >
> > > > I call "final X509Certificate[] certs = req.getCertificates();" and
> > > > use the returned chain for the check.
> > > >
> > > > Now back to the relevant part.
> > > > ===
> > > >
> > > > The current implementation of the client certificate chain check
> > > > relies that Jetty already required the client authentication
> > > > (clientauthneeded) and that the certificate is already checked against
> > > > the configured truststore (that contains only a special CA).
> > > >
> > > > As we could rely on a "valid" certifcate I just need to extract the
> > > > information I need from the client certifcate and "all is fine".
> > > >
> > > >
> > > > Now, I need to add another servlet to that custom distribution that
> > > > should work without a client certifcate.
> > > >
> > > > I assume I will need to remove the truststore and clientauth settings
> > > > from the configuration (keep wanted and drop needed?) and check the
> > > > certifcate in the code for "MyServlet" itself.
> > > > I further assume it should work by a filter or in the servlet itself.
> > > >
> > > > Are there better ways to handle two servlet
> > > > * Servlet1 needs client authentication
> > > > * Servlet2 do not use client authentication
> > > >
> > > > How can I trigger the check of the client certificate correctly in the
> > > > servlet / filter to check against a specific truststore?
> > > >
> > > > I am interested in your inputs.
> > > >
> > > > Best regards,
> > > > Markus
> > > >
> > >
> > > --
> > > Jean-Baptiste Onofré
> > > jbonofre@apache.org
> > > http://blog.nanthrax.net
> > > Talend - http://www.talend.com

Re: Karaf, Pax Web, Jetty: "some" client authentication

Posted by Markus Rathgeb <ma...@gmail.com>.
If this already known (WRT to the following comment)?
https://nierbeck.de/2013/01/bind-certain-web-applications-to-specific-httpconnectors/#comment-62

Am Do., 16. Mai 2019 um 20:26 Uhr schrieb Markus Rathgeb <ma...@gmail.com>:
>
> Hi Łukasz, hi JB,
>
> thank you for that information.
>
> I did not found an official documentation for that feature.
>
> I found this one (WRT the information given to me from you):
> * https://ops4j1.jira.com/browse/PAXWEB-396
> * https://nierbeck.de/2013/01/bind-certain-web-applications-to-specific-httpconnectors/
> * http://blog.nanthrax.net/?p=352
> * Source code of Pax Web
>
> I gave it a try using two additional connectors in jetty.xml.
> I used the example that has been present in the current jetty.xml as
> "SelectChannelConnector" did not work ("Caused by:
> java.lang.ClassNotFoundException:
> org.eclipse.jetty.server.nio.SelectChannelConnector not found by
> org.eclipse.jetty.server [62]").
> ===
>     <Call name="addConnector">
>         <Arg>
>             <New class="org.eclipse.jetty.server.ServerConnector">
>                 <Arg name="server"><Ref refid="Server" /></Arg>
>                 <Arg name="factories">
>                     <Array type="org.eclipse.jetty.server.ConnectionFactory">
>                         <Item>
>                             <New
> class="org.eclipse.jetty.server.HttpConnectionFactory">
>                                 <Arg name="config"><Ref
> refid="httpConfig" /></Arg>
>                             </New>
>                         </Item>
>                     </Array>
>                 </Arg>
>                 <Set name="host"><Property name="jetty.host"
> default="localhost" /></Set>
>                 <Set name="port"><Property name="jetty.port"
> default="8201" /></Set>
>                 <Set name="idleTimeout"><Property name="http.timeout"
> default="30000" /></Set>
>                 <Set name="name">conn1</Set>
>             </New>
>         </Arg>
>     </Call>
>     <Call name="addConnector">
>         <Arg>
>             <New class="org.eclipse.jetty.server.ServerConnector">
>                 <Arg name="server"><Ref refid="Server" /></Arg>
>                 <Arg name="factories">
>                     <Array type="org.eclipse.jetty.server.ConnectionFactory">
>                         <Item>
>                             <New
> class="org.eclipse.jetty.server.HttpConnectionFactory">
>                                 <Arg name="config"><Ref
> refid="httpConfig" /></Arg>
>                             </New>
>                         </Item>
>                     </Array>
>                 </Arg>
>                 <Set name="host"><Property name="jetty.host"
> default="localhost" /></Set>
>                 <Set name="port"><Property name="jetty.port"
> default="8202" /></Set>
>                 <Set name="idleTimeout"><Property name="http.timeout"
> default="30000" /></Set>
>                 <Set name="name">conn2</Set>
>             </New>
>         </Arg>
>     </Call>
> ===
>
> So, additional to 8181 there should be two connetors. conn1 on 8201
> and conn2 on 8202.
>
> I created two bundles. Each bundle registers one servlet and use one
> Web-Connector settings:
>
> Bundle 1 - Component:
> ===
> @Component(immediate = true)
> @Header(name = "Web-Connectors", value = "conn1")
> @Header(name = "Web-VirtualHosts", value = "localhost")
> public class ComponentImpl {
>
>     private static final String ALIAS = "/1";
>
>     private final HttpService httpService;
>
>     @Activate
>     public ComponentImpl(final @Reference HttpService httpService)
> throws ServletException, NamespaceException {
>         this.httpService = httpService;
>         httpService.registerServlet(ALIAS, new HttpServlet() {
>
>             @Override
>             protected void doGet(final HttpServletRequest req, final
> HttpServletResponse resp)
>                     throws ServletException, IOException {
>                 final PrintWriter writer = resp.getWriter();
>                 writer.println("This is the servlet: " + ALIAS);
>             }
>
>         }, null, null);
>     }
>
>     @Deactivate
>     public void close() {
>         httpService.unregister(ALIAS);
>     }
>
> }
> ===
>
> The "Bundle 2 - Component" is identicial to the "1" but uses the alias
> "/2" and the "Web-Connectors" "conn2".
>
> But this does not seem to work as expected.
> "/1" and "/2" can be open on port 8181, 8201 and 8202.
>
> So, all of them are available on all connectors.
>
> Can you point me to my misconfiguration?
> Or can you provide me two working demo bundles each of them using
> another connector?
>
> Best regards,
> Markus
>
> Am Do., 16. Mai 2019 um 16:18 Uhr schrieb Jean-Baptiste Onofré
> <jb...@nanthrax.net>:
> >
> > Hi,
> >
> > I'm not sure it's what you are looking for, but you can configure
> > several connectors via jetty.xml (in addition of the default one created
> > by Pax Web), then, you can use "VirtualHost" to deploy a servlet on a
> > specific connector.
> >
> > I blogged about this while ago (http://blog.nanthrax.net/?p=352).
> >
> > Regards
> > JB
> >
> > On 16/05/2019 08:12, Markus Rathgeb wrote:
> > > Hi,
> > >
> > > I assume there are different parties involved, so if this question
> > > should be raised on another mailing list, please can you point me to?
> > >
> > > I am using Karaf + Pax Web + Jetty.
> > >
> > > Currently I build a custom distribution that Pax Web configuration
> > > (org.ops4j.pax.web.cfg) contains also this lines:
> > >
> > > ===
> > > org.ops4j.pax.web.ssl.clientauthwanted = true
> > > org.ops4j.pax.web.ssl.clientauthneeded = true
> > >
> > > org.ops4j.pax.web.ssl.truststore=${karaf.etc}/truststore.jks
> > > org.ops4j.pax.web.ssl.truststore.password=that-is-not-the-real-one
> > > ===
> > >
> > > This distribution contains a bundle that registers a servlet "MyServlet".
> > >
> > > Now, just FYI, I assume not all is relevant:
> > >
> > > ===
> > > "MyServlet" extends the "WebSocketServlet"
> > > (org.eclipse.jetty.websocket.servlet.WebSocketServlet).
> > > Type hierarchy: MyServlet -> WebSocketServlet -> HttpServlet ->
> > > GenericServlet [Servlet, ServletConfig, Serializable].
> > >
> > > The WebSocketServlet requires the implementation of the abstract
> > > method "public abstract void configure(WebSocketServletFactory
> > > factory);"
> > >
> > > In the "configure" implementation is set a "creator".
> > >
> > > factory.setCreator(new MyCreator(...));
> > >
> > > MyCreator implements the following method (required by the
> > > WebSocketCreator interface):
> > >
> > > public @Nullable Object createWebSocket(final ServletUpgradeRequest
> > > req, final ServletUpgradeResponse resp);
> > >
> > > In that method I do a simple certificate check.
> > >
> > > I call "final X509Certificate[] certs = req.getCertificates();" and
> > > use the returned chain for the check.
> > >
> > > Now back to the relevant part.
> > > ===
> > >
> > > The current implementation of the client certificate chain check
> > > relies that Jetty already required the client authentication
> > > (clientauthneeded) and that the certificate is already checked against
> > > the configured truststore (that contains only a special CA).
> > >
> > > As we could rely on a "valid" certifcate I just need to extract the
> > > information I need from the client certifcate and "all is fine".
> > >
> > >
> > > Now, I need to add another servlet to that custom distribution that
> > > should work without a client certifcate.
> > >
> > > I assume I will need to remove the truststore and clientauth settings
> > > from the configuration (keep wanted and drop needed?) and check the
> > > certifcate in the code for "MyServlet" itself.
> > > I further assume it should work by a filter or in the servlet itself.
> > >
> > > Are there better ways to handle two servlet
> > > * Servlet1 needs client authentication
> > > * Servlet2 do not use client authentication
> > >
> > > How can I trigger the check of the client certificate correctly in the
> > > servlet / filter to check against a specific truststore?
> > >
> > > I am interested in your inputs.
> > >
> > > Best regards,
> > > Markus
> > >
> >
> > --
> > Jean-Baptiste Onofré
> > jbonofre@apache.org
> > http://blog.nanthrax.net
> > Talend - http://www.talend.com

Re: Karaf, Pax Web, Jetty: "some" client authentication

Posted by Markus Rathgeb <ma...@gmail.com>.
Hi Łukasz, hi JB,

thank you for that information.

I did not found an official documentation for that feature.

I found this one (WRT the information given to me from you):
* https://ops4j1.jira.com/browse/PAXWEB-396
* https://nierbeck.de/2013/01/bind-certain-web-applications-to-specific-httpconnectors/
* http://blog.nanthrax.net/?p=352
* Source code of Pax Web

I gave it a try using two additional connectors in jetty.xml.
I used the example that has been present in the current jetty.xml as
"SelectChannelConnector" did not work ("Caused by:
java.lang.ClassNotFoundException:
org.eclipse.jetty.server.nio.SelectChannelConnector not found by
org.eclipse.jetty.server [62]").
===
    <Call name="addConnector">
        <Arg>
            <New class="org.eclipse.jetty.server.ServerConnector">
                <Arg name="server"><Ref refid="Server" /></Arg>
                <Arg name="factories">
                    <Array type="org.eclipse.jetty.server.ConnectionFactory">
                        <Item>
                            <New
class="org.eclipse.jetty.server.HttpConnectionFactory">
                                <Arg name="config"><Ref
refid="httpConfig" /></Arg>
                            </New>
                        </Item>
                    </Array>
                </Arg>
                <Set name="host"><Property name="jetty.host"
default="localhost" /></Set>
                <Set name="port"><Property name="jetty.port"
default="8201" /></Set>
                <Set name="idleTimeout"><Property name="http.timeout"
default="30000" /></Set>
                <Set name="name">conn1</Set>
            </New>
        </Arg>
    </Call>
    <Call name="addConnector">
        <Arg>
            <New class="org.eclipse.jetty.server.ServerConnector">
                <Arg name="server"><Ref refid="Server" /></Arg>
                <Arg name="factories">
                    <Array type="org.eclipse.jetty.server.ConnectionFactory">
                        <Item>
                            <New
class="org.eclipse.jetty.server.HttpConnectionFactory">
                                <Arg name="config"><Ref
refid="httpConfig" /></Arg>
                            </New>
                        </Item>
                    </Array>
                </Arg>
                <Set name="host"><Property name="jetty.host"
default="localhost" /></Set>
                <Set name="port"><Property name="jetty.port"
default="8202" /></Set>
                <Set name="idleTimeout"><Property name="http.timeout"
default="30000" /></Set>
                <Set name="name">conn2</Set>
            </New>
        </Arg>
    </Call>
===

So, additional to 8181 there should be two connetors. conn1 on 8201
and conn2 on 8202.

I created two bundles. Each bundle registers one servlet and use one
Web-Connector settings:

Bundle 1 - Component:
===
@Component(immediate = true)
@Header(name = "Web-Connectors", value = "conn1")
@Header(name = "Web-VirtualHosts", value = "localhost")
public class ComponentImpl {

    private static final String ALIAS = "/1";

    private final HttpService httpService;

    @Activate
    public ComponentImpl(final @Reference HttpService httpService)
throws ServletException, NamespaceException {
        this.httpService = httpService;
        httpService.registerServlet(ALIAS, new HttpServlet() {

            @Override
            protected void doGet(final HttpServletRequest req, final
HttpServletResponse resp)
                    throws ServletException, IOException {
                final PrintWriter writer = resp.getWriter();
                writer.println("This is the servlet: " + ALIAS);
            }

        }, null, null);
    }

    @Deactivate
    public void close() {
        httpService.unregister(ALIAS);
    }

}
===

The "Bundle 2 - Component" is identicial to the "1" but uses the alias
"/2" and the "Web-Connectors" "conn2".

But this does not seem to work as expected.
"/1" and "/2" can be open on port 8181, 8201 and 8202.

So, all of them are available on all connectors.

Can you point me to my misconfiguration?
Or can you provide me two working demo bundles each of them using
another connector?

Best regards,
Markus

Am Do., 16. Mai 2019 um 16:18 Uhr schrieb Jean-Baptiste Onofré
<jb...@nanthrax.net>:
>
> Hi,
>
> I'm not sure it's what you are looking for, but you can configure
> several connectors via jetty.xml (in addition of the default one created
> by Pax Web), then, you can use "VirtualHost" to deploy a servlet on a
> specific connector.
>
> I blogged about this while ago (http://blog.nanthrax.net/?p=352).
>
> Regards
> JB
>
> On 16/05/2019 08:12, Markus Rathgeb wrote:
> > Hi,
> >
> > I assume there are different parties involved, so if this question
> > should be raised on another mailing list, please can you point me to?
> >
> > I am using Karaf + Pax Web + Jetty.
> >
> > Currently I build a custom distribution that Pax Web configuration
> > (org.ops4j.pax.web.cfg) contains also this lines:
> >
> > ===
> > org.ops4j.pax.web.ssl.clientauthwanted = true
> > org.ops4j.pax.web.ssl.clientauthneeded = true
> >
> > org.ops4j.pax.web.ssl.truststore=${karaf.etc}/truststore.jks
> > org.ops4j.pax.web.ssl.truststore.password=that-is-not-the-real-one
> > ===
> >
> > This distribution contains a bundle that registers a servlet "MyServlet".
> >
> > Now, just FYI, I assume not all is relevant:
> >
> > ===
> > "MyServlet" extends the "WebSocketServlet"
> > (org.eclipse.jetty.websocket.servlet.WebSocketServlet).
> > Type hierarchy: MyServlet -> WebSocketServlet -> HttpServlet ->
> > GenericServlet [Servlet, ServletConfig, Serializable].
> >
> > The WebSocketServlet requires the implementation of the abstract
> > method "public abstract void configure(WebSocketServletFactory
> > factory);"
> >
> > In the "configure" implementation is set a "creator".
> >
> > factory.setCreator(new MyCreator(...));
> >
> > MyCreator implements the following method (required by the
> > WebSocketCreator interface):
> >
> > public @Nullable Object createWebSocket(final ServletUpgradeRequest
> > req, final ServletUpgradeResponse resp);
> >
> > In that method I do a simple certificate check.
> >
> > I call "final X509Certificate[] certs = req.getCertificates();" and
> > use the returned chain for the check.
> >
> > Now back to the relevant part.
> > ===
> >
> > The current implementation of the client certificate chain check
> > relies that Jetty already required the client authentication
> > (clientauthneeded) and that the certificate is already checked against
> > the configured truststore (that contains only a special CA).
> >
> > As we could rely on a "valid" certifcate I just need to extract the
> > information I need from the client certifcate and "all is fine".
> >
> >
> > Now, I need to add another servlet to that custom distribution that
> > should work without a client certifcate.
> >
> > I assume I will need to remove the truststore and clientauth settings
> > from the configuration (keep wanted and drop needed?) and check the
> > certifcate in the code for "MyServlet" itself.
> > I further assume it should work by a filter or in the servlet itself.
> >
> > Are there better ways to handle two servlet
> > * Servlet1 needs client authentication
> > * Servlet2 do not use client authentication
> >
> > How can I trigger the check of the client certificate correctly in the
> > servlet / filter to check against a specific truststore?
> >
> > I am interested in your inputs.
> >
> > Best regards,
> > Markus
> >
>
> --
> Jean-Baptiste Onofré
> jbonofre@apache.org
> http://blog.nanthrax.net
> Talend - http://www.talend.com

Re: Karaf, Pax Web, Jetty: "some" client authentication

Posted by Jean-Baptiste Onofré <jb...@nanthrax.net>.
Hi,

I'm not sure it's what you are looking for, but you can configure
several connectors via jetty.xml (in addition of the default one created
by Pax Web), then, you can use "VirtualHost" to deploy a servlet on a
specific connector.

I blogged about this while ago (http://blog.nanthrax.net/?p=352).

Regards
JB

On 16/05/2019 08:12, Markus Rathgeb wrote:
> Hi,
> 
> I assume there are different parties involved, so if this question
> should be raised on another mailing list, please can you point me to?
> 
> I am using Karaf + Pax Web + Jetty.
> 
> Currently I build a custom distribution that Pax Web configuration
> (org.ops4j.pax.web.cfg) contains also this lines:
> 
> ===
> org.ops4j.pax.web.ssl.clientauthwanted = true
> org.ops4j.pax.web.ssl.clientauthneeded = true
> 
> org.ops4j.pax.web.ssl.truststore=${karaf.etc}/truststore.jks
> org.ops4j.pax.web.ssl.truststore.password=that-is-not-the-real-one
> ===
> 
> This distribution contains a bundle that registers a servlet "MyServlet".
> 
> Now, just FYI, I assume not all is relevant:
> 
> ===
> "MyServlet" extends the "WebSocketServlet"
> (org.eclipse.jetty.websocket.servlet.WebSocketServlet).
> Type hierarchy: MyServlet -> WebSocketServlet -> HttpServlet ->
> GenericServlet [Servlet, ServletConfig, Serializable].
> 
> The WebSocketServlet requires the implementation of the abstract
> method "public abstract void configure(WebSocketServletFactory
> factory);"
> 
> In the "configure" implementation is set a "creator".
> 
> factory.setCreator(new MyCreator(...));
> 
> MyCreator implements the following method (required by the
> WebSocketCreator interface):
> 
> public @Nullable Object createWebSocket(final ServletUpgradeRequest
> req, final ServletUpgradeResponse resp);
> 
> In that method I do a simple certificate check.
> 
> I call "final X509Certificate[] certs = req.getCertificates();" and
> use the returned chain for the check.
> 
> Now back to the relevant part.
> ===
> 
> The current implementation of the client certificate chain check
> relies that Jetty already required the client authentication
> (clientauthneeded) and that the certificate is already checked against
> the configured truststore (that contains only a special CA).
> 
> As we could rely on a "valid" certifcate I just need to extract the
> information I need from the client certifcate and "all is fine".
> 
> 
> Now, I need to add another servlet to that custom distribution that
> should work without a client certifcate.
> 
> I assume I will need to remove the truststore and clientauth settings
> from the configuration (keep wanted and drop needed?) and check the
> certifcate in the code for "MyServlet" itself.
> I further assume it should work by a filter or in the servlet itself.
> 
> Are there better ways to handle two servlet
> * Servlet1 needs client authentication
> * Servlet2 do not use client authentication
> 
> How can I trigger the check of the client certificate correctly in the
> servlet / filter to check against a specific truststore?
> 
> I am interested in your inputs.
> 
> Best regards,
> Markus
> 

-- 
Jean-Baptiste Onofré
jbonofre@apache.org
http://blog.nanthrax.net
Talend - http://www.talend.com

Re: Karaf, Pax Web, Jetty: "some" client authentication

Posted by Łukasz Dywicki <lu...@code-house.org>.
Can you use two sockets/connectors?
Jetty stuff is configured at connector level, before even servlet is
reached. I know its not a perfect solution, rather a workaround..

Best regards,
Łukasz
--
Code-House
http://code-house.org


On 16.05.2019 08:12, Markus Rathgeb wrote:
> Hi,
> 
> I assume there are different parties involved, so if this question
> should be raised on another mailing list, please can you point me to?
> 
> I am using Karaf + Pax Web + Jetty.
> 
> Currently I build a custom distribution that Pax Web configuration
> (org.ops4j.pax.web.cfg) contains also this lines:
> 
> ===
> org.ops4j.pax.web.ssl.clientauthwanted = true
> org.ops4j.pax.web.ssl.clientauthneeded = true
> 
> org.ops4j.pax.web.ssl.truststore=${karaf.etc}/truststore.jks
> org.ops4j.pax.web.ssl.truststore.password=that-is-not-the-real-one
> ===
> 
> This distribution contains a bundle that registers a servlet "MyServlet".
> 
> Now, just FYI, I assume not all is relevant:
> 
> ===
> "MyServlet" extends the "WebSocketServlet"
> (org.eclipse.jetty.websocket.servlet.WebSocketServlet).
> Type hierarchy: MyServlet -> WebSocketServlet -> HttpServlet ->
> GenericServlet [Servlet, ServletConfig, Serializable].
> 
> The WebSocketServlet requires the implementation of the abstract
> method "public abstract void configure(WebSocketServletFactory
> factory);"
> 
> In the "configure" implementation is set a "creator".
> 
> factory.setCreator(new MyCreator(...));
> 
> MyCreator implements the following method (required by the
> WebSocketCreator interface):
> 
> public @Nullable Object createWebSocket(final ServletUpgradeRequest
> req, final ServletUpgradeResponse resp);
> 
> In that method I do a simple certificate check.
> 
> I call "final X509Certificate[] certs = req.getCertificates();" and
> use the returned chain for the check.
> 
> Now back to the relevant part.
> ===
> 
> The current implementation of the client certificate chain check
> relies that Jetty already required the client authentication
> (clientauthneeded) and that the certificate is already checked against
> the configured truststore (that contains only a special CA).
> 
> As we could rely on a "valid" certifcate I just need to extract the
> information I need from the client certifcate and "all is fine".
> 
> 
> Now, I need to add another servlet to that custom distribution that
> should work without a client certifcate.
> 
> I assume I will need to remove the truststore and clientauth settings
> from the configuration (keep wanted and drop needed?) and check the
> certifcate in the code for "MyServlet" itself.
> I further assume it should work by a filter or in the servlet itself.
> 
> Are there better ways to handle two servlet
> * Servlet1 needs client authentication
> * Servlet2 do not use client authentication
> 
> How can I trigger the check of the client certificate correctly in the
> servlet / filter to check against a specific truststore?
> 
> I am interested in your inputs.
> 
> Best regards,
> Markus
>