Skip to content

Commit

Permalink
Merge pull request #32584 from sberyozkin/management_basic_main_oidc
Browse files Browse the repository at this point in the history
Add JWT authentication tests to management-interface-auth
  • Loading branch information
cescoffier committed Apr 18, 2023
2 parents 0dec6f9 + 62d4fd2 commit 9066163
Show file tree
Hide file tree
Showing 6 changed files with 160 additions and 1 deletion.
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();
}

}

0 comments on commit 9066163

Please sign in to comment.