Merge pull request #374 from DataDog/mar-kolya/add-servlet-auth-tests
Add tests to servlet intrumentation to verify that username is set co…
This commit is contained in:
commit
05ef9ce8bd
|
@ -5,10 +5,18 @@ import datadog.trace.agent.test.TestUtils
|
||||||
import datadog.trace.api.DDSpanTypes
|
import datadog.trace.api.DDSpanTypes
|
||||||
import datadog.trace.common.writer.ListWriter
|
import datadog.trace.common.writer.ListWriter
|
||||||
import io.opentracing.util.GlobalTracer
|
import io.opentracing.util.GlobalTracer
|
||||||
|
import okhttp3.Credentials
|
||||||
import okhttp3.Interceptor
|
import okhttp3.Interceptor
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
|
import org.eclipse.jetty.http.HttpHeaders
|
||||||
|
import org.eclipse.jetty.http.security.Constraint
|
||||||
|
import org.eclipse.jetty.security.ConstraintMapping
|
||||||
|
import org.eclipse.jetty.security.ConstraintSecurityHandler
|
||||||
|
import org.eclipse.jetty.security.HashLoginService
|
||||||
|
import org.eclipse.jetty.security.LoginService
|
||||||
|
import org.eclipse.jetty.security.authentication.BasicAuthenticator
|
||||||
import org.eclipse.jetty.server.Server
|
import org.eclipse.jetty.server.Server
|
||||||
import org.eclipse.jetty.servlet.ServletContextHandler
|
import org.eclipse.jetty.servlet.ServletContextHandler
|
||||||
|
|
||||||
|
@ -34,9 +42,9 @@ class JettyServlet2Test extends AgentTestRunner {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
// Uncomment when debugging:
|
// Uncomment when debugging:
|
||||||
.connectTimeout(1, TimeUnit.HOURS)
|
// .connectTimeout(1, TimeUnit.HOURS)
|
||||||
.writeTimeout(1, TimeUnit.HOURS)
|
// .writeTimeout(1, TimeUnit.HOURS)
|
||||||
.readTimeout(1, TimeUnit.HOURS)
|
// .readTimeout(1, TimeUnit.HOURS)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
private Server jettyServer
|
private Server jettyServer
|
||||||
|
@ -55,7 +63,11 @@ class JettyServlet2Test extends AgentTestRunner {
|
||||||
jettyServer = new Server(PORT)
|
jettyServer = new Server(PORT)
|
||||||
servletContext = new ServletContextHandler()
|
servletContext = new ServletContextHandler()
|
||||||
|
|
||||||
|
ConstraintSecurityHandler security = setupAuthentication(jettyServer)
|
||||||
|
|
||||||
|
servletContext.setSecurityHandler(security)
|
||||||
servletContext.addServlet(TestServlet2.Sync, "/sync")
|
servletContext.addServlet(TestServlet2.Sync, "/sync")
|
||||||
|
servletContext.addServlet(TestServlet2.Sync, "/auth/sync")
|
||||||
|
|
||||||
jettyServer.setHandler(servletContext)
|
jettyServer.setHandler(servletContext)
|
||||||
jettyServer.start()
|
jettyServer.start()
|
||||||
|
@ -82,11 +94,13 @@ class JettyServlet2Test extends AgentTestRunner {
|
||||||
|
|
||||||
def "test #path servlet call"() {
|
def "test #path servlet call"() {
|
||||||
setup:
|
setup:
|
||||||
def request = new Request.Builder()
|
def requestBuilder = new Request.Builder()
|
||||||
.url("http://localhost:$PORT/$path")
|
.url("http://localhost:$PORT/$path")
|
||||||
.get()
|
.get()
|
||||||
.build()
|
if (auth) {
|
||||||
def response = client.newCall(request).execute()
|
requestBuilder.header(HttpHeaders.AUTHORIZATION, Credentials.basic("user", "password"))
|
||||||
|
}
|
||||||
|
def response = client.newCall(requestBuilder.build()).execute()
|
||||||
|
|
||||||
expect:
|
expect:
|
||||||
response.body().string().trim() == expectedResponse
|
response.body().string().trim() == expectedResponse
|
||||||
|
@ -107,6 +121,9 @@ class JettyServlet2Test extends AgentTestRunner {
|
||||||
"component" "java-web-servlet"
|
"component" "java-web-servlet"
|
||||||
"span.type" DDSpanTypes.WEB_SERVLET
|
"span.type" DDSpanTypes.WEB_SERVLET
|
||||||
"servlet.context" ""
|
"servlet.context" ""
|
||||||
|
if (auth) {
|
||||||
|
"user.principal" "user"
|
||||||
|
}
|
||||||
defaultTags()
|
defaultTags()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -114,8 +131,9 @@ class JettyServlet2Test extends AgentTestRunner {
|
||||||
}
|
}
|
||||||
|
|
||||||
where:
|
where:
|
||||||
path | expectedResponse
|
path | expectedResponse | auth
|
||||||
"sync" | "Hello Sync"
|
"sync" | "Hello Sync" | false
|
||||||
|
"auth/sync" | "Hello Sync" | true
|
||||||
}
|
}
|
||||||
|
|
||||||
def "test #path error servlet call"() {
|
def "test #path error servlet call"() {
|
||||||
|
@ -195,4 +213,37 @@ class JettyServlet2Test extends AgentTestRunner {
|
||||||
path | expectedResponse
|
path | expectedResponse
|
||||||
"sync" | "Hello Sync"
|
"sync" | "Hello Sync"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup simple authentication for tests
|
||||||
|
* <p>
|
||||||
|
* requests to {@code /auth/*} need login 'user' and password 'password'
|
||||||
|
* <p>
|
||||||
|
* For details @see <a href="http://www.eclipse.org/jetty/documentation/9.3.x/embedded-examples.html">http://www.eclipse.org/jetty/documentation/9.3.x/embedded-examples.html</a>
|
||||||
|
*
|
||||||
|
* @param jettyServer server to attach login service
|
||||||
|
* @return SecurityHandler that can be assigned to servlet
|
||||||
|
*/
|
||||||
|
private ConstraintSecurityHandler setupAuthentication(Server jettyServer) {
|
||||||
|
ConstraintSecurityHandler security = new ConstraintSecurityHandler()
|
||||||
|
|
||||||
|
Constraint constraint = new Constraint()
|
||||||
|
constraint.setName("auth")
|
||||||
|
constraint.setAuthenticate(true)
|
||||||
|
constraint.setRoles("role")
|
||||||
|
|
||||||
|
ConstraintMapping mapping = new ConstraintMapping()
|
||||||
|
mapping.setPathSpec("/auth/*")
|
||||||
|
mapping.setConstraint(constraint)
|
||||||
|
|
||||||
|
security.setConstraintMappings(mapping)
|
||||||
|
security.setAuthenticator(new BasicAuthenticator())
|
||||||
|
|
||||||
|
LoginService loginService = new HashLoginService("TestRealm",
|
||||||
|
"src/test/resources/realm.properties")
|
||||||
|
security.setLoginService(loginService)
|
||||||
|
jettyServer.addBean(loginService)
|
||||||
|
|
||||||
|
security
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
user: password,role
|
|
@ -5,12 +5,20 @@ import datadog.trace.agent.test.TestUtils
|
||||||
import datadog.trace.api.DDSpanTypes
|
import datadog.trace.api.DDSpanTypes
|
||||||
import datadog.trace.common.writer.ListWriter
|
import datadog.trace.common.writer.ListWriter
|
||||||
import io.opentracing.util.GlobalTracer
|
import io.opentracing.util.GlobalTracer
|
||||||
|
import okhttp3.Credentials
|
||||||
import okhttp3.Interceptor
|
import okhttp3.Interceptor
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
|
import org.eclipse.jetty.http.HttpHeaders
|
||||||
|
import org.eclipse.jetty.security.ConstraintMapping
|
||||||
|
import org.eclipse.jetty.security.ConstraintSecurityHandler
|
||||||
|
import org.eclipse.jetty.security.HashLoginService
|
||||||
|
import org.eclipse.jetty.security.LoginService
|
||||||
|
import org.eclipse.jetty.security.authentication.BasicAuthenticator
|
||||||
import org.eclipse.jetty.server.Server
|
import org.eclipse.jetty.server.Server
|
||||||
import org.eclipse.jetty.servlet.ServletContextHandler
|
import org.eclipse.jetty.servlet.ServletContextHandler
|
||||||
|
import org.eclipse.jetty.util.security.Constraint
|
||||||
|
|
||||||
import java.lang.reflect.Field
|
import java.lang.reflect.Field
|
||||||
import java.util.concurrent.CountDownLatch
|
import java.util.concurrent.CountDownLatch
|
||||||
|
@ -35,9 +43,9 @@ class JettyServlet3Test extends AgentTestRunner {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
// Uncomment when debugging:
|
// Uncomment when debugging:
|
||||||
// .connectTimeout(1, TimeUnit.HOURS)
|
// .connectTimeout(1, TimeUnit.HOURS)
|
||||||
// .writeTimeout(1, TimeUnit.HOURS)
|
// .writeTimeout(1, TimeUnit.HOURS)
|
||||||
// .readTimeout(1, TimeUnit.HOURS)
|
// .readTimeout(1, TimeUnit.HOURS)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
private Server jettyServer
|
private Server jettyServer
|
||||||
|
@ -56,8 +64,13 @@ class JettyServlet3Test extends AgentTestRunner {
|
||||||
jettyServer = new Server(PORT)
|
jettyServer = new Server(PORT)
|
||||||
servletContext = new ServletContextHandler()
|
servletContext = new ServletContextHandler()
|
||||||
|
|
||||||
|
ConstraintSecurityHandler security = setupAuthentication(jettyServer)
|
||||||
|
|
||||||
|
servletContext.setSecurityHandler(security)
|
||||||
servletContext.addServlet(TestServlet3.Sync, "/sync")
|
servletContext.addServlet(TestServlet3.Sync, "/sync")
|
||||||
|
servletContext.addServlet(TestServlet3.Sync, "/auth/sync")
|
||||||
servletContext.addServlet(TestServlet3.Async, "/async")
|
servletContext.addServlet(TestServlet3.Async, "/async")
|
||||||
|
servletContext.addServlet(TestServlet3.Async, "/auth/async")
|
||||||
|
|
||||||
jettyServer.setHandler(servletContext)
|
jettyServer.setHandler(servletContext)
|
||||||
jettyServer.start()
|
jettyServer.start()
|
||||||
|
@ -84,11 +97,13 @@ class JettyServlet3Test extends AgentTestRunner {
|
||||||
|
|
||||||
def "test #path servlet call"() {
|
def "test #path servlet call"() {
|
||||||
setup:
|
setup:
|
||||||
def request = new Request.Builder()
|
def requestBuilder = new Request.Builder()
|
||||||
.url("http://localhost:$PORT/$path")
|
.url("http://localhost:$PORT/$path")
|
||||||
.get()
|
.get()
|
||||||
.build()
|
if (auth) {
|
||||||
def response = client.newCall(request).execute()
|
requestBuilder.header(HttpHeaders.AUTHORIZATION, Credentials.basic("user", "password"))
|
||||||
|
}
|
||||||
|
def response = client.newCall(requestBuilder.build()).execute()
|
||||||
|
|
||||||
expect:
|
expect:
|
||||||
response.body().string().trim() == expectedResponse
|
response.body().string().trim() == expectedResponse
|
||||||
|
@ -110,6 +125,9 @@ class JettyServlet3Test extends AgentTestRunner {
|
||||||
"span.type" DDSpanTypes.WEB_SERVLET
|
"span.type" DDSpanTypes.WEB_SERVLET
|
||||||
"servlet.context" ""
|
"servlet.context" ""
|
||||||
"http.status_code" 200
|
"http.status_code" 200
|
||||||
|
if (auth) {
|
||||||
|
"user.principal" "user"
|
||||||
|
}
|
||||||
defaultTags()
|
defaultTags()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -117,9 +135,11 @@ class JettyServlet3Test extends AgentTestRunner {
|
||||||
}
|
}
|
||||||
|
|
||||||
where:
|
where:
|
||||||
path | expectedResponse
|
path | expectedResponse | auth
|
||||||
"async" | "Hello Async"
|
"async" | "Hello Async" | false
|
||||||
"sync" | "Hello Sync"
|
"sync" | "Hello Sync" | false
|
||||||
|
"auth/async" | "Hello Async" | true
|
||||||
|
"auth/sync" | "Hello Sync" | true
|
||||||
}
|
}
|
||||||
|
|
||||||
def "servlet instrumentation clears state after async request"() {
|
def "servlet instrumentation clears state after async request"() {
|
||||||
|
@ -227,4 +247,37 @@ class JettyServlet3Test extends AgentTestRunner {
|
||||||
path | expectedResponse
|
path | expectedResponse
|
||||||
"sync" | "Hello Sync"
|
"sync" | "Hello Sync"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup simple authentication for tests
|
||||||
|
* <p>
|
||||||
|
* requests to {@code /auth/*} need login 'user' and password 'password'
|
||||||
|
* <p>
|
||||||
|
* For details @see <a href="http://www.eclipse.org/jetty/documentation/9.3.x/embedded-examples.html">http://www.eclipse.org/jetty/documentation/9.3.x/embedded-examples.html</a>
|
||||||
|
*
|
||||||
|
* @param jettyServer server to attach login service
|
||||||
|
* @return SecurityHandler that can be assigned to servlet
|
||||||
|
*/
|
||||||
|
private ConstraintSecurityHandler setupAuthentication(Server jettyServer) {
|
||||||
|
ConstraintSecurityHandler security = new ConstraintSecurityHandler()
|
||||||
|
|
||||||
|
Constraint constraint = new Constraint()
|
||||||
|
constraint.setName("auth")
|
||||||
|
constraint.setAuthenticate(true)
|
||||||
|
constraint.setRoles("role")
|
||||||
|
|
||||||
|
ConstraintMapping mapping = new ConstraintMapping()
|
||||||
|
mapping.setPathSpec("/auth/*")
|
||||||
|
mapping.setConstraint(constraint)
|
||||||
|
|
||||||
|
security.setConstraintMappings(mapping)
|
||||||
|
security.setAuthenticator(new BasicAuthenticator())
|
||||||
|
|
||||||
|
LoginService loginService = new HashLoginService("TestRealm",
|
||||||
|
"src/test/resources/realm.properties")
|
||||||
|
security.setLoginService(loginService)
|
||||||
|
jettyServer.addBean(loginService)
|
||||||
|
|
||||||
|
security
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
user: password,role
|
Loading…
Reference in New Issue