Hi, 

I'm trying to create an API with Rest DSL and Swagger Java components. For 
hosting the API I want to use Jetty and use Basic Authentication to secure it.

With Jetty 8 the code below works, but with Camel 2.18.1 my code fails in Jetty 
9 with this error:
No LoginService for org.eclipse.jetty.security.authentication.BasicAuthenticator

It seems that when the security handler is re-added for the api-docs, the 
loginService is gone and can not be found anymore in the beans store of the 
server. I see in Jetty configuration examples that the loginService is also 
added as a bean to the Jetty server. If it has been added, it can be found when 
re-adding the security handler.

How can I solve this error?

Kind regards,

Remco Schoen


camel-context.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans";
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
       xsi:schemaLocation="
         http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans.xsd
         http://camel.apache.org/schema/spring 
http://camel.apache.org/schema/spring/camel-spring.xsd";>

  <bean id="constraint" class="org.eclipse.jetty.util.security.Constraint">
    <property name="name" value="BASIC"/>
    <property name="roles" value="rolename"/>
    <property name="authenticate" value="true"/>
  </bean>

  <bean id="constraintMapping" 
class="org.eclipse.jetty.security.ConstraintMapping">
    <property name="constraint" ref="constraint"/>
    <property name="pathSpec" value="/*"/>
  </bean>

  <bean id="myLoginService" 
class="com.mooreds.camel.security.HardcodedLoginService"/>

  <bean id="securityHandler" 
class="org.eclipse.jetty.security.ConstraintSecurityHandler">
    <property name="constraintMappings">
      <list>
        <ref bean="constraintMapping"/>
      </list>
    </property>
    <property name="authenticator">
      <bean 
class="org.eclipse.jetty.security.authentication.BasicAuthenticator"/>
    </property>
    <property name="loginService" ref="myLoginService"/>
  </bean>

  <camelContext xmlns="http://camel.apache.org/schema/spring";>
    <restConfiguration component="jetty"
                       bindingMode="json"
                       port="8080"
                       apiContextPath="api-docs"
                       apiContextListing="true"
                       enableCORS="true"
    >
      <endpointProperty key="handlers" value="securityHandler"/>
      <dataFormatProperty key="prettyPrint" value="true"/>
      <apiProperty key="api.version" value="5"/>
      <apiProperty key="api.title" value="TOPdesk integration"/>
      <apiProperty key="api.description" value="TOPdesk integration"/>
      <apiProperty key="cors" value="true"/>
    </restConfiguration>

    <rest>
      <get uri="/ping">
        <route>
          <setBody>
            <constant>SUCCESS</constant>
          </setBody>
        </route>
      </get>
    </rest>

  </camelContext>
</beans>


HardcodedLoginService.java

package com.mooreds.camel.security;

import org.eclipse.jetty.security.DefaultIdentityService;
import org.eclipse.jetty.security.IdentityService;
import org.eclipse.jetty.security.LoginService;
import org.eclipse.jetty.security.MappedLoginService;
import org.eclipse.jetty.server.UserIdentity;
import org.eclipse.jetty.util.security.Credential;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.security.auth.Subject;
import java.security.Principal;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class HardcodedLoginService implements LoginService {
    private final static Logger log = 
LoggerFactory.getLogger(HardcodedLoginService.class);

    private final Map users = new ConcurrentHashMap();

    // matches what is in the constraint object in the spring config
    private final String[] ACCESS_ROLE = new String[] { "rolename" };
        
    private IdentityService identityService = new DefaultIdentityService();

        public IdentityService getIdentityService() {
                return identityService;
        }

        public String getName() {
                return "";
        }

        public UserIdentity login(String username, Object creds) {
                
        UserIdentity user = null;

        // HERE IS THE HARDCODING
                boolean validUser = "ralph".equals(username) && 
"s3cr3t".equals(creds);
                if (validUser) {
                        Credential credential = (creds instanceof 
Credential)?(Credential)creds:Credential.getCredential(creds.toString());

                    Principal userPrincipal = new 
MappedLoginService.KnownUser(username,credential);
                    Subject subject = new Subject();
                    subject.getPrincipals().add(userPrincipal);
                    subject.getPrivateCredentials().add(creds);
                    subject.setReadOnly();
                    user=identityService.newUserIdentity(subject,userPrincipal, 
ACCESS_ROLE);
                    users.put(user.getUserPrincipal().getName(), true);
                }

            return (user != null) ? user : null;
        }

        public void logout(UserIdentity arg0) {
                
        }

        public void setIdentityService(IdentityService arg0) {
             this.identityService = arg0;
                
        }

        public boolean validate(UserIdentity user) {
                if (users.containsKey(user.getUserPrincipal().getName()))
            return true;

        return false;   
        }
}

log:

2016-12-06 13:41:52,681 [main           ] INFO  ClassPathXmlApplicationContext 
- Refreshing 
org.springframework.context.support.ClassPathXmlApplicationContext@2a3046da: 
startup date [Tue Dec 06 13:41:52 CET 2016]; root of context hierarchy
2016-12-06 13:41:52,745 [main           ] INFO  XmlBeanDefinitionReader        
- Loading XML bean definitions from file 
[/Users/remcos/topdesk/customer/jetty_basic_authentication/build/resources/main/META-INF/spring/camel-context.xml]
2016-12-06 13:41:54,653 [main           ] INFO  log                            
- Logging initialized @2496ms
2016-12-06 13:41:55,725 [main           ] INFO  DefaultTypeConverter           
- Loaded 197 type converters
2016-12-06 13:41:55,765 [main           ] INFO  SpringCamelContext             
- Apache Camel 2.18.1 (CamelContext: camel-1) is starting
2016-12-06 13:41:55,767 [main           ] INFO  ManagedManagementStrategy      
- JMX is enabled
2016-12-06 13:41:56,102 [main           ] INFO  DefaultRuntimeEndpointRegistry 
- Runtime endpoint registry is in extended mode gathering usage statistics of 
all incoming and outgoing endpoints (cache limit: 1000)
2016-12-06 13:41:56,378 [main           ] INFO  SpringCamelContext             
- StreamCaching is not in use. If using streams then its recommended to enable 
stream caching. See more details at http://camel.apache.org/stream-caching.html
2016-12-06 13:41:57,221 [main           ] INFO  Server                         
- jetty-9.2.19.v20160908
2016-12-06 13:41:57,248 [main           ] INFO  ContextHandler                 
- Started o.e.j.s.ServletContextHandler@543e593{/,null,AVAILABLE}
2016-12-06 13:41:57,273 [main           ] INFO  ServerConnector                
- Started ServerConnector@2b214b94{HTTP/1.1}{0.0.0.0:8080}
2016-12-06 13:41:57,274 [main           ] INFO  Server                         
- Started @5129ms
2016-12-06 13:41:57,275 [main           ] INFO  SpringCamelContext             
- Route: route1 started and consuming from: 
jetty:http://0.0.0.0:8080/ping?httpMethodRestrict=GET%2COPTIONS&optionsEnabled=true
2016-12-06 13:41:57,295 [main           ] INFO  ServerConnector                
- Stopped ServerConnector@2b214b94{HTTP/1.1}{0.0.0.0:8080}
2016-12-06 13:41:57,298 [main           ] INFO  ContextHandler                 
- Stopped o.e.j.s.ServletContextHandler@543e593{/,null,UNAVAILABLE}
2016-12-06 13:41:57,301 [main           ] INFO  Server                         
- jetty-9.2.19.v20160908
2016-12-06 13:41:57,303 [main           ] WARN  AbstractLifeCycle              
- FAILED org.eclipse.jetty.security.ConstraintSecurityHandler@985696: 
java.lang.IllegalStateException: No LoginService for 
org.eclipse.jetty.security.authentication.BasicAuthenticator@7c455e96 in 
org.eclipse.jetty.security.ConstraintSecurityHandler@985696
java.lang.IllegalStateException: No LoginService for 
org.eclipse.jetty.security.authentication.BasicAuthenticator@7c455e96 in 
org.eclipse.jetty.security.ConstraintSecurityHandler@985696
        at 
org.eclipse.jetty.security.authentication.LoginAuthenticator.setConfiguration(LoginAuthenticator.java:76)
        at 
org.eclipse.jetty.security.SecurityHandler.doStart(SecurityHandler.java:384)
        at 
org.eclipse.jetty.security.ConstraintSecurityHandler.doStart(ConstraintSecurityHandler.java:449)
        at 
org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
        at 
org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132)
        at org.eclipse.jetty.server.Server.start(Server.java:387)
        at 
org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:106)
        at 
org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61)
        at org.eclipse.jetty.server.Server.doStart(Server.java:354)
        at 
org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
        at 
org.apache.camel.component.jetty.JettyHttpComponent.connect(JettyHttpComponent.java:351)
        at 
org.apache.camel.http.common.HttpCommonEndpoint.connect(HttpCommonEndpoint.java:143)
        at 
org.apache.camel.http.common.HttpConsumer.doStart(HttpConsumer.java:54)
        at org.apache.camel.support.ServiceSupport.start(ServiceSupport.java:61)
        at 
org.apache.camel.impl.DefaultCamelContext.startService(DefaultCamelContext.java:3371)
        at 
org.apache.camel.impl.DefaultCamelContext.doStartOrResumeRouteConsumers(DefaultCamelContext.java:3688)
        at 
org.apache.camel.impl.DefaultCamelContext.doStartRouteConsumers(DefaultCamelContext.java:3624)
        at 
org.apache.camel.impl.DefaultCamelContext.safelyStartRouteServices(DefaultCamelContext.java:3544)
        at 
org.apache.camel.impl.DefaultCamelContext.doStartOrResumeRoutes(DefaultCamelContext.java:3308)
        at 
org.apache.camel.impl.DefaultCamelContext.doStartCamel(DefaultCamelContext.java:3162)
        at 
org.apache.camel.impl.DefaultCamelContext.access$000(DefaultCamelContext.java:182)
        at 
org.apache.camel.impl.DefaultCamelContext$2.call(DefaultCamelContext.java:2957)
        at 
org.apache.camel.impl.DefaultCamelContext$2.call(DefaultCamelContext.java:2953)
        at 
org.apache.camel.impl.DefaultCamelContext.doWithDefinedClassLoader(DefaultCamelContext.java:2976)
        at 
org.apache.camel.impl.DefaultCamelContext.doStart(DefaultCamelContext.java:2953)
        at org.apache.camel.support.ServiceSupport.start(ServiceSupport.java:61)
        at 
org.apache.camel.impl.DefaultCamelContext.start(DefaultCamelContext.java:2920)
        at 
org.apache.camel.spring.SpringCamelContext.maybeStart(SpringCamelContext.java:275)
        at 
org.apache.camel.spring.SpringCamelContext.onApplicationEvent(SpringCamelContext.java:136)
        at 
org.apache.camel.spring.CamelContextFactoryBean.onApplicationEvent(CamelContextFactoryBean.java:353)
        at 
org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:166)
        at 
org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:138)
        at 
org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:383)
        at 
org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:337)
        at 
org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:882)
        at 
org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:545)
        at 
org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
        at 
org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:93)
        at 
org.apache.camel.spring.Main.createDefaultApplicationContext(Main.java:222)
        at org.apache.camel.spring.Main.doStart(Main.java:154)
        at org.apache.camel.support.ServiceSupport.start(ServiceSupport.java:61)
        at org.apache.camel.main.MainSupport.run(MainSupport.java:138)
        at org.apache.camel.main.MainSupport.run(MainSupport.java:390)
        at org.apache.camel.spring.Main.main(Main.java:86)
2016-12-06 13:41:57,325 [main           ] INFO  ServerConnector                
- Started ServerConnector@2b214b94{HTTP/1.1}{0.0.0.0:8080}
2016-12-06 13:41:57,326 [main           ] WARN  AbstractLifeCycle              
- FAILED org.eclipse.jetty.server.Server@45792847: 
java.lang.IllegalStateException: No LoginService for 
org.eclipse.jetty.security.authentication.BasicAuthenticator@7c455e96 in 
org.eclipse.jetty.security.ConstraintSecurityHandler@985696
java.lang.IllegalStateException: No LoginService for 
org.eclipse.jetty.security.authentication.BasicAuthenticator@7c455e96 in 
org.eclipse.jetty.security.ConstraintSecurityHandler@985696
        at 
org.eclipse.jetty.security.authentication.LoginAuthenticator.setConfiguration(LoginAuthenticator.java:76)
        at 
org.eclipse.jetty.security.SecurityHandler.doStart(SecurityHandler.java:384)
        at 
org.eclipse.jetty.security.ConstraintSecurityHandler.doStart(ConstraintSecurityHandler.java:449)
        at 
org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
        at 
org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132)
        at org.eclipse.jetty.server.Server.start(Server.java:387)
        at 
org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:106)
        at 
org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61)
        at org.eclipse.jetty.server.Server.doStart(Server.java:354)
        at 
org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
        at 
org.apache.camel.component.jetty.JettyHttpComponent.connect(JettyHttpComponent.java:351)
        at 
org.apache.camel.http.common.HttpCommonEndpoint.connect(HttpCommonEndpoint.java:143)
        at 
org.apache.camel.http.common.HttpConsumer.doStart(HttpConsumer.java:54)
        at org.apache.camel.support.ServiceSupport.start(ServiceSupport.java:61)
        at 
org.apache.camel.impl.DefaultCamelContext.startService(DefaultCamelContext.java:3371)
        at 
org.apache.camel.impl.DefaultCamelContext.doStartOrResumeRouteConsumers(DefaultCamelContext.java:3688)
        at 
org.apache.camel.impl.DefaultCamelContext.doStartRouteConsumers(DefaultCamelContext.java:3624)
        at 
org.apache.camel.impl.DefaultCamelContext.safelyStartRouteServices(DefaultCamelContext.java:3544)
        at 
org.apache.camel.impl.DefaultCamelContext.doStartOrResumeRoutes(DefaultCamelContext.java:3308)
        at 
org.apache.camel.impl.DefaultCamelContext.doStartCamel(DefaultCamelContext.java:3162)
        at 
org.apache.camel.impl.DefaultCamelContext.access$000(DefaultCamelContext.java:182)
        at 
org.apache.camel.impl.DefaultCamelContext$2.call(DefaultCamelContext.java:2957)
        at 
org.apache.camel.impl.DefaultCamelContext$2.call(DefaultCamelContext.java:2953)
        at 
org.apache.camel.impl.DefaultCamelContext.doWithDefinedClassLoader(DefaultCamelContext.java:2976)
        at 
org.apache.camel.impl.DefaultCamelContext.doStart(DefaultCamelContext.java:2953)
        at org.apache.camel.support.ServiceSupport.start(ServiceSupport.java:61)
        at 
org.apache.camel.impl.DefaultCamelContext.start(DefaultCamelContext.java:2920)
        at 
org.apache.camel.spring.SpringCamelContext.maybeStart(SpringCamelContext.java:275)
        at 
org.apache.camel.spring.SpringCamelContext.onApplicationEvent(SpringCamelContext.java:136)
        at 
org.apache.camel.spring.CamelContextFactoryBean.onApplicationEvent(CamelContextFactoryBean.java:353)
        at 
org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:166)
        at 
org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:138)
        at 
org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:383)
        at 
org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:337)
        at 
org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:882)
        at 
org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:545)
        at 
org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
        at 
org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:93)
        at 
org.apache.camel.spring.Main.createDefaultApplicationContext(Main.java:222)
        at org.apache.camel.spring.Main.doStart(Main.java:154)
        at org.apache.camel.support.ServiceSupport.start(ServiceSupport.java:61)
        at org.apache.camel.main.MainSupport.run(MainSupport.java:138)
        at org.apache.camel.main.MainSupport.run(MainSupport.java:390)
        at org.apache.camel.spring.Main.main(Main.java:86)
2016-12-06 13:41:57,365 [main           ] INFO  ServerConnector                
- Stopped ServerConnector@2b214b94{HTTP/1.1}{0.0.0.0:8080}
2016-12-06 13:41:57,366 [main           ] INFO  SpringCamelContext             
- Apache Camel 2.18.1 (CamelContext: camel-1) is shutting down
2016-12-06 13:41:57,367 [main           ] INFO  DefaultShutdownStrategy        
- Starting to graceful shutdown 1 routes (timeout 300 seconds)
2016-12-06 13:41:57,389 [ - ShutdownTask] INFO  DefaultShutdownStrategy        
- Route: route1 shutdown complete, was consuming from: 
jetty:http://0.0.0.0:8080/ping?httpMethodRestrict=GET%2COPTIONS&optionsEnabled=true
2016-12-06 13:41:57,390 [main           ] INFO  DefaultShutdownStrategy        
- Graceful shutdown of 1 routes completed in 0 seconds
2016-12-06 13:41:57,431 [main           ] INFO  SpringCamelContext             
- Apache Camel 2.18.1 (CamelContext: camel-1) uptime 1.664 seconds
2016-12-06 13:41:57,432 [main           ] INFO  SpringCamelContext             
- Apache Camel 2.18.1 (CamelContext: camel-1) is shutdown in 0.063 seconds

Reply via email to