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.common.writer.ListWriter
|
||||
import io.opentracing.util.GlobalTracer
|
||||
import okhttp3.Credentials
|
||||
import okhttp3.Interceptor
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
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.servlet.ServletContextHandler
|
||||
|
||||
|
@ -34,9 +42,9 @@ class JettyServlet2Test extends AgentTestRunner {
|
|||
}
|
||||
})
|
||||
// Uncomment when debugging:
|
||||
.connectTimeout(1, TimeUnit.HOURS)
|
||||
.writeTimeout(1, TimeUnit.HOURS)
|
||||
.readTimeout(1, TimeUnit.HOURS)
|
||||
// .connectTimeout(1, TimeUnit.HOURS)
|
||||
// .writeTimeout(1, TimeUnit.HOURS)
|
||||
// .readTimeout(1, TimeUnit.HOURS)
|
||||
.build()
|
||||
|
||||
private Server jettyServer
|
||||
|
@ -55,7 +63,11 @@ class JettyServlet2Test extends AgentTestRunner {
|
|||
jettyServer = new Server(PORT)
|
||||
servletContext = new ServletContextHandler()
|
||||
|
||||
ConstraintSecurityHandler security = setupAuthentication(jettyServer)
|
||||
|
||||
servletContext.setSecurityHandler(security)
|
||||
servletContext.addServlet(TestServlet2.Sync, "/sync")
|
||||
servletContext.addServlet(TestServlet2.Sync, "/auth/sync")
|
||||
|
||||
jettyServer.setHandler(servletContext)
|
||||
jettyServer.start()
|
||||
|
@ -82,11 +94,13 @@ class JettyServlet2Test extends AgentTestRunner {
|
|||
|
||||
def "test #path servlet call"() {
|
||||
setup:
|
||||
def request = new Request.Builder()
|
||||
def requestBuilder = new Request.Builder()
|
||||
.url("http://localhost:$PORT/$path")
|
||||
.get()
|
||||
.build()
|
||||
def response = client.newCall(request).execute()
|
||||
if (auth) {
|
||||
requestBuilder.header(HttpHeaders.AUTHORIZATION, Credentials.basic("user", "password"))
|
||||
}
|
||||
def response = client.newCall(requestBuilder.build()).execute()
|
||||
|
||||
expect:
|
||||
response.body().string().trim() == expectedResponse
|
||||
|
@ -107,6 +121,9 @@ class JettyServlet2Test extends AgentTestRunner {
|
|||
"component" "java-web-servlet"
|
||||
"span.type" DDSpanTypes.WEB_SERVLET
|
||||
"servlet.context" ""
|
||||
if (auth) {
|
||||
"user.principal" "user"
|
||||
}
|
||||
defaultTags()
|
||||
}
|
||||
}
|
||||
|
@ -114,8 +131,9 @@ class JettyServlet2Test extends AgentTestRunner {
|
|||
}
|
||||
|
||||
where:
|
||||
path | expectedResponse
|
||||
"sync" | "Hello Sync"
|
||||
path | expectedResponse | auth
|
||||
"sync" | "Hello Sync" | false
|
||||
"auth/sync" | "Hello Sync" | true
|
||||
}
|
||||
|
||||
def "test #path error servlet call"() {
|
||||
|
@ -195,4 +213,37 @@ class JettyServlet2Test extends AgentTestRunner {
|
|||
path | expectedResponse
|
||||
"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.common.writer.ListWriter
|
||||
import io.opentracing.util.GlobalTracer
|
||||
import okhttp3.Credentials
|
||||
import okhttp3.Interceptor
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
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.servlet.ServletContextHandler
|
||||
import org.eclipse.jetty.util.security.Constraint
|
||||
|
||||
import java.lang.reflect.Field
|
||||
import java.util.concurrent.CountDownLatch
|
||||
|
@ -35,9 +43,9 @@ class JettyServlet3Test extends AgentTestRunner {
|
|||
}
|
||||
})
|
||||
// Uncomment when debugging:
|
||||
// .connectTimeout(1, TimeUnit.HOURS)
|
||||
// .writeTimeout(1, TimeUnit.HOURS)
|
||||
// .readTimeout(1, TimeUnit.HOURS)
|
||||
// .connectTimeout(1, TimeUnit.HOURS)
|
||||
// .writeTimeout(1, TimeUnit.HOURS)
|
||||
// .readTimeout(1, TimeUnit.HOURS)
|
||||
.build()
|
||||
|
||||
private Server jettyServer
|
||||
|
@ -56,8 +64,13 @@ class JettyServlet3Test extends AgentTestRunner {
|
|||
jettyServer = new Server(PORT)
|
||||
servletContext = new ServletContextHandler()
|
||||
|
||||
ConstraintSecurityHandler security = setupAuthentication(jettyServer)
|
||||
|
||||
servletContext.setSecurityHandler(security)
|
||||
servletContext.addServlet(TestServlet3.Sync, "/sync")
|
||||
servletContext.addServlet(TestServlet3.Sync, "/auth/sync")
|
||||
servletContext.addServlet(TestServlet3.Async, "/async")
|
||||
servletContext.addServlet(TestServlet3.Async, "/auth/async")
|
||||
|
||||
jettyServer.setHandler(servletContext)
|
||||
jettyServer.start()
|
||||
|
@ -84,11 +97,13 @@ class JettyServlet3Test extends AgentTestRunner {
|
|||
|
||||
def "test #path servlet call"() {
|
||||
setup:
|
||||
def request = new Request.Builder()
|
||||
def requestBuilder = new Request.Builder()
|
||||
.url("http://localhost:$PORT/$path")
|
||||
.get()
|
||||
.build()
|
||||
def response = client.newCall(request).execute()
|
||||
if (auth) {
|
||||
requestBuilder.header(HttpHeaders.AUTHORIZATION, Credentials.basic("user", "password"))
|
||||
}
|
||||
def response = client.newCall(requestBuilder.build()).execute()
|
||||
|
||||
expect:
|
||||
response.body().string().trim() == expectedResponse
|
||||
|
@ -110,6 +125,9 @@ class JettyServlet3Test extends AgentTestRunner {
|
|||
"span.type" DDSpanTypes.WEB_SERVLET
|
||||
"servlet.context" ""
|
||||
"http.status_code" 200
|
||||
if (auth) {
|
||||
"user.principal" "user"
|
||||
}
|
||||
defaultTags()
|
||||
}
|
||||
}
|
||||
|
@ -117,9 +135,11 @@ class JettyServlet3Test extends AgentTestRunner {
|
|||
}
|
||||
|
||||
where:
|
||||
path | expectedResponse
|
||||
"async" | "Hello Async"
|
||||
"sync" | "Hello Sync"
|
||||
path | expectedResponse | auth
|
||||
"async" | "Hello Async" | false
|
||||
"sync" | "Hello Sync" | false
|
||||
"auth/async" | "Hello Async" | true
|
||||
"auth/sync" | "Hello Sync" | true
|
||||
}
|
||||
|
||||
def "servlet instrumentation clears state after async request"() {
|
||||
|
@ -227,4 +247,37 @@ class JettyServlet3Test extends AgentTestRunner {
|
|||
path | expectedResponse
|
||||
"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