I am following this tutorial instruction: http://www.eclipse.org/jetty/documentation/current/spnego-support.html
It says the following: A corresponding UserRealm needs to be created either programmatically if embedded, via the jetty.xml or in a context file for the webapp.
Now I am using embedded jetty and I could create a web.xml using the WebAppContext and \jee but what is the context file? Is it talking about something like a Spring context?
(I am fairly new to Java)
With context file for the webapp, they probably mean the jetty.xml configuration file, which can also be used on a per-app basis, when you name it jetty-web.xml and place it in your WEB-INF directory (alongside the web.xml configuration file).
Frame of a jetty-web.xml:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE Configure PUBLIC "//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
<!-- configuration here -->
</Configure>
You can configure your realms with it, e.g.:
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
<Set name="contextPath">/test</Set>
<Set name="war"><SystemProperty name="jetty.home" default="."/>/webapps/test</Set>
<Get name="securityHandler">
<Set name="loginService">
<New class="org.eclipse.jetty.security.HashLoginService">
<Set name="name">Test Realm</Set>
<Set name="config"><SystemProperty name="jetty.home" default="."/>/etc/realm.properties</Set>
</New>
</Set>
</Get>
</Configure>
For details, see:
https://wiki.eclipse.org/Jetty/Reference/jetty-web.xml
https://wiki.eclipse.org/Jetty/Tutorial/Realms
Since you are using embedded jetty, I am unsure if you can configure user realms using the normal jetty-web.xml configuration, or if you have to set them up programmatically.
I did this programmatically, but with an older (6.1) version of Jetty. But I also have used the jetty-web.xml in an embedded jetty to configure some parameters, e.g. the upload file size limit.
Related
In a spring-boot app, how do I stop Jetty from extracting the War file ?
I want to stop Jetty from extracting the War because the directory where it is supposed to be extracted is always empty. I thought stopping Jetty from extracting and use the WAR file as-is may be an option but I have added jetty-web.xml to my /WEB-INF/ directory but it did not help.
jetty-web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC
"-//Mort Bay Consulting//DTD Configure//EN"
"http://www.eclipse.org/jetty/configure_9_3.dtd">
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
<Set name="extractWAR">false</Set>
</Configure>
Jetty doesn't seem to look at this setting.
Jetty logs:
Started o.s.b.c.e.j.JettyEmbeddedWebAppContext#bfe845{/app,[file:///apps/app-1/tmp/jetty-docbase.8731890992893272407.8888/],AVAILABLE}
But the directory: /apps/app-1/tmp/jetty-docbase.8731890992893272407.8888/ is always empty.
Why didn't Jetty populate this directory?
Any help would be appreciated.
Thanks in advance,
Lee
/apps/app-1/tmp/jetty-docbase.8731890992893272407.8888/ is your work directory for that webapp.
If you set <Set name="extractWAR">false</Set> then it's only used for work files during runtime, not for extracted content of your webapp. This is mandatory, part of the Servlet spec, and cannot be avoided.
Your XML is incomplete (missing war reference and contextPath setting) and invalid (dtd reference).
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC
"-//Jetty//Configure//EN"
"http://www.eclipse.org/jetty/configure_9_3.dtd">
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
<Set name="war">/path/to/your/app.war</Set>
<Set name="contextPath">/myapp</Set>
<Set name="extractWAR">false</Set>
</Configure>
We are running multiple Java webapps which use Jetty9 as server.
The apps are reachable via subdirectories:
domain.tld/app1
domain.tld/app2
domain.tld/app3
Now I want to protect two of those apps via basic auth.
When using Apache as server this would be quite easy to achieve via .htaccess or the vhost conf file, but how can I achieve this with Jetty?
Unfortunately the Jetty docs didn't help me.
Thanks in advance.
EDIT: Now I got the following in my jetty-context.xml, but nothing happens:
<?xml version='1.0' encoding='utf-8'?>
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
<Set name="contextPath">/app1</Set>
<Set name="war">/opt/software/web/view.war</Set>
<Set name="handler">
<New class="org.eclipse.jetty.server.handler.RequestLogHandler" id="RequestLog">
<Set name="requestLog">
<New class="org.eclipse.jetty.server.NCSARequestLog" id="RequestLogImpl">
<Set name="filename">/home/software/something/log/access-something-yyyy_mm_dd.request.log</Set>
<Set name="filenameDateFormat">yyyy_MM_dd</Set>
<Set name="logTimeZone">GMT</Set>
<Set name="retainDays">90</Set>
<Set name="append">true</Set>
<Set name="logLatency">true</Set>
</New>
</Set>
</New>
</Set>
<Get name="securityHandler">
<Set name="loginService">
<New class="org.eclipse.jetty.security.HashLoginService">
<Set name="name">Software</Set>
<Set name="config"><SystemProperty name="jetty.home" default="."/>/etc/software/realm.properties</Set>
<Call name="start"></Call>
</New>
</Set>
</Get>
</Configure>
Content of realm.properties:
admin: password,admin,user
You need to set up something to trigger the authentication. Based on what you've provided, BASIC auth should suit your needs. You've already declared the HashLoginService in your context XML file, but you also need to declare the auth type in the WEB-INF/web.xml of the webapp itself. This would look something like:
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>My Realm</realm-name>
</login-config>
You also need to define the security/auth constraints of the auth method in the web.xml. This helps determine who is allowed access to what, based on role, URL..etc. An example of restricting the webapp entirely might look like:
<security-constraint>
<web-resource-collection>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
<role-name>other</role-name>
<role-name>roles</role-name>
</auth-constraint>
</security-constraint>
Jetty supports other Authentication mechanisms as well if something better suits your needs.
So to recap, to scope your security per webapp you need to do a few things:
Declare the type of authentication for the webapp in the WEB-INF/web.xml
Define the security/auth constraints for the webapp in the WEB-INF/web.xml
Define the type of the LoginService (Hash in this case) in the context XML file for the webapp, and provide the path to the associated properties file.
I need to use https for jetty maven plugin.
I googled following answer
https://stackoverflow.com/a/3795116/2674303
But looks like this answer is not suitable for jetty-maven-plugin of 9 version.
idea complains about syntax
How to fix my problem?
Ok, since jetty-9.0 it is no longer possible to configure a https connector directly in the pom.xml: you need to use jetty xml config files to do it.
I am new to exchange ,so excuse my code copy/paste.
jetty.xml
<New id="httpConfig" class="org.eclipse.jetty.server.HttpConfiguration">
<Set name="secureScheme">https</Set>
<Set name="securePort"><Property name="jetty.secure.port" default="8443" /></Set>
<Set name="outputBufferSize">32768</Set>
<Set name="requestHeaderSize">8192</Set>
<Set name="responseHeaderSize">8192</Set>
<Set name="sendServerVersion">true</Set>
<Set name="sendDateHeader">false</Set>
<Set name="headerCacheSize">512</Set>
<!-- Uncomment to enable handling of X-Forwarded- style headers
<Call name="addCustomizer">
<Arg><New class="org.eclipse.jetty.server.ForwardedRequestCustomizer"/>
</Arg>
</Call>
-->
</New>
Look here, for whole bunch of xml's and if it is helpful please check my answer as correct
In order to have custom session storage I have implemented a custom sessionManager (by extending NoSqlSessionManager) and sessionIdManager. My code (along with jars it requires) went into ${jetty.home}/lib/ext (version 8.1.4 BTW). With start.ini i included another config file with following content:
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<Set name="sessionIdManager">
<New id="customIdMgr" class="com.me.customSessionIdManager">
<Arg>...</Arg>
</New>
</Set>
</Configure>
Jetty starts and sessionIdManager appears to be working. At least scavenge() method is being called. So far so good. Next step is to associate my custom sessionManager with the WebAppContext of my choice. I did it within the overlay template (overlay.xml) with following content:
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
<Get name="server">
<Get id="customIdMgr" name="sessionIdManager"/>
</Get>
<Set name="sessionHandler">
<New class="org.eclipse.jetty.server.session.SessionHandler">
<Arg>
<New class="com.me.customSessionManager">
<Set name="sessionIdManager"><Ref id="customIdMgr"/></Set>
</New>
</Arg>
</New>
</Set>
</Configure>
However when starting Jetty I get this:
WARN:oejx.XmlConfiguration:Config error at <Get id="customIdMgr" name="sessionIdManager"/> java.lang.NullPointerException
...which implies that the object that was registered in the main jetty configuration is now gone when overlays are processed.
Any idea what I'm doing wrong here?
After quite a lot of debugging it turns out, the root of the problem is <Get name="server"> returns null. Most probably reference to Server class is injected into WebAppContext much later in the deployment process. So instead of getting Server i referenced it with <Ref id="Server"> and that did the trick.
I'm trying to define two data sources in my web application, using the jetty-env.xml file.
It works ok with just one data source, however I get this exception when the second data source is added:
java.lang.IllegalStateException: Nothing to bind for name javax.sql.DataSource/default
Here's my configuration:
jetty-env.xml
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
<New id="ds" class="org.eclipse.jetty.plus.jndi.Resource">
<Arg>jdbc/mybd1</Arg>
<Arg>
<New class="com.mchange.v2.c3p0.ComboPooledDataSource">
<Set name="driverClass">com.microsoft.sqlserver.jdbc.SQLServerDriver</Set>
<Set name="jdbcUrl">jdbc:jtds:sqlserver://url:1433/mybd1</Set>
<Set name="user">xx</Set>
<Set name="password">yy</Set>
</New>
</Arg>
</New>
<New id="ds2" class="org.eclipse.jetty.plus.jndi.Resource" >
<Arg>jdbc/mybd2</Arg>
<Arg>
<New class="com.mchange.v2.c3p0.ComboPooledDataSource">
<Set name="driverClass">com.microsoft.sqlserver.jdbc.SQLServerDriver</Set>
<Set name="jdbcUrl">jdbc:jtds:sqlserver://url:1433/mybd2</Set>
<Set name="user">xx</Set>
<Set name="password">yy</Set>
</New>
</Arg>
</New>
</Configure>
web.xml
<resource-ref>
<res-ref-name>jdbc/mybd1</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
<resource-ref>
<res-ref-name>jdbc/mybd2</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
hibernate.cfg.xml (there is another hibernate.cfb.xml to configure the second data source)
<session-factory>
<property name="connection.datasource">jdbc/mybd1</property>
<!-- ... -->
Any clue?
I haven't had a chance to test it, but it looks to me like your problem is that you're missing an <Arg /> for the scope.
Your DS should be:
<New id="ds" class="org.eclipse.jetty.plus.jndi.Resource">
<Arg></Arg>
<Arg>jdbc/mybd1</Arg>
<Arg>
<New class="com.mchange.v2.c3p0.ComboPooledDataSource">
etc.
That first "Arg" is the scope, and without it, the rest of your arguments are out of position, and are probably causing your issue.
The id parameter values should match in jetty-env.xml and web.xml
jetty-env.xml
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
<New id="DS1" class="org.eclipse.jetty.plus.jndi.Resource">...</New>
<New id="DS2" class="org.eclipse.jetty.plus.jndi.Resource">...</New>
</Configure>
web.xml
<resource-ref id="DS1">...</resource-ref>
<resource-ref id="DS2">...</resource-ref>
Try to enable logging in Jetty.
Be carefull logger name is "jndi".
Jetty developers don't use class-name as a logger-name for JNDI.
I spent 2 days to finding difference between name defined in web.xml and jetty-env.xml.
Take a look in :
https://www.eclipse.org/jetty/documentation/9.4.x/using-jetty-jndi.html
Deciding Where to Declare Resources
You can define naming resources in three places:
jetty.xml
Naming resources defined in a jetty.xml file are scoped at either the JVM level or the Server level.
The classes for the resource must be visible at the Jetty container level. If the classes for the resource only exist inside your webapp, you must declare it in a WEB-INF/jetty-env.xml file.
WEB-INF/jetty-env.xml
Naming resources in a WEB-INF/jetty-env.xml file are scoped to the web app in which the file resides. While you can enter JVM or Server scopes if you choose, we do not recommend doing so. The resources defined here may use classes from inside your webapp. This is a Jetty-specific mechanism.
Context xml file
Entries in a context xml file should be scoped at the level of the webapp to which they apply, although you can supply a less strict scoping level of Server or JVM if you choose. As with resources declared in a jetty.xml file, classes associated with the resource must be visible on the container’s classpath.
And put a file like this :
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
<!-- Add an EnvEntry only valid for this webapp -->
<New id="gargle" class="org.eclipse.jetty.plus.jndi.EnvEntry">
<Arg>gargle</Arg>
<Arg type="java.lang.Double">100</Arg>
<Arg type="boolean">true</Arg>
</New>
<!-- Add an override for a global EnvEntry -->
<New id="wiggle" class="org.eclipse.jetty.plus.jndi.EnvEntry">
<Arg>wiggle</Arg>
<Arg type="java.lang.Double">55.0</Arg>
<Arg type="boolean">true</Arg>
</New>
<!-- an XADataSource -->
<New id="mydatasource99" class="org.eclipse.jetty.plus.jndi.Resource">
<Arg>jdbc/mydatasource99</Arg>
<Arg>
<New class="com.atomikos.jdbc.SimpleDataSourceBean">
<Set name="xaDataSourceClassName">org.apache.derby.jdbc.EmbeddedXADataSource</Set>
<Set name="xaDataSourceProperties">databaseName=testdb99;createDatabase=create</Set>
<Set name="UniqueResourceName">mydatasource99</Set>
</New>
</Arg>
</New>
</Configure>