Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add JWT authentication tests to management-interface-auth #32584

Merged
merged 1 commit into from
Apr 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
17 changes: 17 additions & 0 deletions integration-tests/management-interface-auth/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@
<groupId>io.quarkus</groupId>
<artifactId>quarkus-elytron-security-properties-file</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-jwt</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
Expand Down Expand Up @@ -99,6 +103,19 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-jwt-deployment</artifactId>
<version>${project.version}</version>
<type>pom</type>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,16 @@ public String hello() {
public String goodbye() {
return "goodbye";
}

@GET
@Path("/goodmorning")
public String goodmorning() {
return "goodmorning";
}

@GET
@Path("/goodevening")
public String goodevening() {
return "goodevening";
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,28 @@
quarkus.management.enabled=true
# Management router authentication:
# /q/health/* - basic authentication only, `management` role is required
# /q/metrics/* - basic and jwt authentications are allowed, any role is allowed
quarkus.management.auth.basic=true
quarkus.management.auth.policy.role-policy.roles-allowed=management
quarkus.management.auth.permission.health.paths=/q/health/*
quarkus.management.auth.permission.health.policy=role-policy
quarkus.management.auth.permission.health.auth-mechanism=basic

quarkus.management.auth.permission.metrics.paths=/q/metrics/*
quarkus.management.auth.permission.metrics.policy=authenticated

# Main router authentication:
# /service/hello/* - public resource
# /service/goodbye/* - basic authentication only, `greeting` role is allowed
# /service/goodmorning/* - JWT bearer authentication only, `admin` role is allowed
# /service/goodevening/* - JWT bearer authentication only, `user` role is allowed

quarkus.http.auth.basic=true
quarkus.http.auth.policy.role-policy.roles-allowed=greeting

quarkus.http.auth.permission.main.paths=/service/goodbye
quarkus.http.auth.permission.main.policy=role-policy
quarkus.http.auth.permission.main.auth-mechanism=basic

quarkus.security.users.embedded.enabled=true
quarkus.security.users.embedded.plain-text=true
Expand All @@ -18,3 +31,18 @@ quarkus.security.users.embedded.roles.alice=management

quarkus.security.users.embedded.users.bob=bob
quarkus.security.users.embedded.roles.bob=greeting

quarkus.http.auth.policy.role-policy-jwt-admin.roles-allowed=admin
quarkus.http.auth.permission.main-jwt-admin.paths=/service/goodmorning
quarkus.http.auth.permission.main-jwt-admin.policy=role-policy-jwt-admin
quarkus.http.auth.permission.main-jwt-admin.auth-mechanism=bearer

quarkus.http.auth.policy.role-policy-jwt-user.roles-allowed=user
quarkus.http.auth.permission.main-jwt-user.paths=/service/goodevening
quarkus.http.auth.permission.main-jwt-user.policy=role-policy-jwt-user
quarkus.http.auth.permission.main-jwt-user.auth-mechanism=bearer

mp.jwt.verify.publickey.location=/publicKey.pem
mp.jwt.verify.issuer=https://server.example.com
smallrye.jwt.sign.key.location=/privateKey.pem
smallrye.jwt.new-token.issuer=https://server.example.com
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCWK8UjyoHgPTLa
PLQJ8SoXLLjpHSjtLxMqmzHnFscqhTVVaDpCRCb6e3Ii/WniQTWw8RA7vf4djz4H
OzvlfBFNgvUGZHXDwnmGaNVaNzpHYFMEYBhE8VGGiveSkzqeLZI+Y02G6sQAfDtN
qqzM/l5QX8X34oQFaTBW1r49nftvCpITiwJvWyhkWtXP9RP8sXi1im5Vi3dhupOh
nelk5n0BfajUYIbfHA6ORzjHRbt7NtBl0L2J+0/FUdHyKs6KMlFGNw8O0Dq88qnM
uXoLJiewhg9332W3DFMeOveel+//cvDnRsCRtPgd4sXFPHh+UShkso7+DRsChXa6
oGGQD3GdAgMBAAECggEAAjfTSZwMHwvIXIDZB+yP+pemg4ryt84iMlbofclQV8hv
6TsI4UGwcbKxFOM5VSYxbNOisb80qasb929gixsyBjsQ8284bhPJR7r0q8h1C+jY
URA6S4pk8d/LmFakXwG9Tz6YPo3pJziuh48lzkFTk0xW2Dp4SLwtAptZY/+ZXyJ6
96QXDrZKSSM99Jh9s7a0ST66WoxSS0UC51ak+Keb0KJ1jz4bIJ2C3r4rYlSu4hHB
Y73GfkWORtQuyUDa9yDOem0/z0nr6pp+pBSXPLHADsqvZiIhxD/O0Xk5I6/zVHB3
zuoQqLERk0WvA8FXz2o8AYwcQRY2g30eX9kU4uDQAQKBgQDmf7KGImUGitsEPepF
KH5yLWYWqghHx6wfV+fdbBxoqn9WlwcQ7JbynIiVx8MX8/1lLCCe8v41ypu/eLtP
iY1ev2IKdrUStvYRSsFigRkuPHUo1ajsGHQd+ucTDf58mn7kRLW1JGMeGxo/t32B
m96Af6AiPWPEJuVfgGV0iwg+HQKBgQCmyPzL9M2rhYZn1AozRUguvlpmJHU2DpqS
34Q+7x2Ghf7MgBUhqE0t3FAOxEC7IYBwHmeYOvFR8ZkVRKNF4gbnF9RtLdz0DMEG
5qsMnvJUSQbNB1yVjUCnDAtElqiFRlQ/k0LgYkjKDY7LfciZl9uJRl0OSYeX/qG2
tRW09tOpgQKBgBSGkpM3RN/MRayfBtmZvYjVWh3yjkI2GbHA1jj1g6IebLB9SnfL
WbXJErCj1U+wvoPf5hfBc7m+jRgD3Eo86YXibQyZfY5pFIh9q7Ll5CQl5hj4zc4Y
b16sFR+xQ1Q9Pcd+BuBWmSz5JOE/qcF869dthgkGhnfVLt/OQzqZluZRAoGAXQ09
nT0TkmKIvlza5Af/YbTqEpq8mlBDhTYXPlWCD4+qvMWpBII1rSSBtftgcgca9XLB
MXmRMbqtQeRtg4u7dishZVh1MeP7vbHsNLppUQT9Ol6lFPsd2xUpJDc6BkFat62d
Xjr3iWNPC9E9nhPPdCNBv7reX7q81obpeXFMXgECgYEAmk2Qlus3OV0tfoNRqNpe
Mb0teduf2+h3xaI1XDIzPVtZF35ELY/RkAHlmWRT4PCdR0zXDidE67L6XdJyecSt
FdOUH8z5qUraVVebRFvJqf/oGsXc4+ex1ZKUTbY0wqY1y9E39yvB3MaTmZFuuqk8
f3cg+fr8aou7pr9SHhJlZCU=
-----END PRIVATE KEY-----
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlivFI8qB4D0y2jy0CfEq
Fyy46R0o7S8TKpsx5xbHKoU1VWg6QkQm+ntyIv1p4kE1sPEQO73+HY8+Bzs75XwR
TYL1BmR1w8J5hmjVWjc6R2BTBGAYRPFRhor3kpM6ni2SPmNNhurEAHw7TaqszP5e
UF/F9+KEBWkwVta+PZ37bwqSE4sCb1soZFrVz/UT/LF4tYpuVYt3YbqToZ3pZOZ9
AX2o1GCG3xwOjkc4x0W7ezbQZdC9iftPxVHR8irOijJRRjcPDtA6vPKpzLl6CyYn
sIYPd99ltwxTHjr3npfv/3Lw50bAkbT4HeLFxTx4flEoZLKO/g0bAoV2uqBhkA9x
nQIDAQAB
-----END PUBLIC KEY-----
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package io.quarkus.it.management;

import java.util.Set;

import org.hamcrest.Matchers;
import org.junit.jupiter.api.Test;

import io.quarkus.test.junit.QuarkusTest;
import io.restassured.RestAssured;
import io.smallrye.jwt.build.Jwt;

@QuarkusTest
public class ManagementInterfaceTestCase {
Expand All @@ -29,6 +32,11 @@ void verifyThatHealthChecksAreExposedOnManagementInterface() {
.then().statusCode(200)
.body(Matchers.containsString("UP"));

RestAssured.given().auth().oauth2(getAdminToken()).get(getPrefix() + "/q/health")
.then().statusCode(401);
RestAssured.given().auth().oauth2(getUserToken()).get(getPrefix() + "/q/health")
.then().statusCode(401);

RestAssured.get("/q/health")
.then().statusCode(404);
}
Expand All @@ -44,12 +52,19 @@ void verifyThatMetricsAreExposedOnManagementInterface() {
RestAssured.given().auth().basic("john", "john").get(getPrefix() + "/q/metrics")
.then().statusCode(401);

RestAssured.given().auth().oauth2(getAdminToken()).get(getPrefix() + "/q/metrics")
.then().statusCode(200);
RestAssured.given().auth().oauth2(getUserToken()).get(getPrefix() + "/q/metrics")
.then().statusCode(200);
RestAssured.given().auth().oauth2("wrongtoken").get(getPrefix() + "/q/metrics")
.then().statusCode(401);

RestAssured.get("/q/metrics")
.then().statusCode(404);
}

@Test
void verifyMainEndpoint() {
void verifyMainEndpointBasicAuth() {
RestAssured.get("/service/hello").then().statusCode(200)
.body(Matchers.equalTo("hello"));

Expand All @@ -62,5 +77,55 @@ void verifyMainEndpoint() {
RestAssured.given().auth().basic("bob", "bob").get("/service/goodbye")
.then().statusCode(200)
.body(Matchers.equalTo("goodbye"));

RestAssured.given().auth().oauth2(getAdminToken()).get("/service/goodbye")
.then().statusCode(401);
RestAssured.given().auth().oauth2(getUserToken()).get("/service/goodbye")
.then().statusCode(401);

}

@Test
void verifyMainEndpointJwtAuth() {
RestAssured.get("/service/hello").then().statusCode(200)
.body(Matchers.equalTo("hello"));

RestAssured.given().auth().preemptive().basic("john", "john").get("/service/goodmorning")
.then().statusCode(401);
RestAssured.given().auth().preemptive().basic("john", "john").get("/service/goodevening")
.then().statusCode(401);

RestAssured.given().auth().preemptive().basic("alice", "alice").get("/service/goodmorning")
.then().statusCode(401);
RestAssured.given().auth().preemptive().basic("alice", "alice").get("/service/goodevening")
.then().statusCode(401);

RestAssured.given().auth().basic("bob", "bob").get("/service/goodmorning")
.then().statusCode(401);
RestAssured.given().auth().basic("bob", "bob").get("/service/goodevening")
.then().statusCode(401);

RestAssured.given().auth().oauth2(getAdminToken()).get("/service/goodmorning")
.then().statusCode(200)
.body(Matchers.equalTo("goodmorning"));
RestAssured.given().auth().oauth2(getUserToken()).get("/service/goodmorning")
.then().statusCode(403);

RestAssured.given().auth().oauth2(getAdminToken()).get("/service/goodevening")
.then().statusCode(200)
.body(Matchers.equalTo("goodevening"));
RestAssured.given().auth().oauth2(getUserToken()).get("/service/goodevening")
.then().statusCode(200)
.body(Matchers.equalTo("goodevening"));

}

private String getAdminToken() {
return Jwt.upn("alice").groups(Set.of("admin", "user")).sign();
}

private String getUserToken() {
return Jwt.subject("bob").groups("user").sign();
}

}