forked from quarkusio/quarkus
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request quarkusio#16362 from sberyozkin/test_security_jwt
Add test-security-jwt and test-security-oidc modules
- Loading branch information
Showing
21 changed files
with
552 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -813,6 +813,7 @@ Please see link:security-openid-connect-client#token-propagation[Token Propagati | |
[[integration-testing]] | ||
== Testing | ||
|
||
[[integration-testing-wiremock]] | ||
=== Wiremock | ||
|
||
If you configure `mp.jwt.verify.publickey.location` to point to HTTPS or HTTP based JsonWebKey (JWK) set then you can use the same approach as described in the link:security-openid-connect#integration-testing[OpenId Connect Bearer Token Integration testing] `Wiremock` section but only change the `application.properties` to use MP JWT configuration properties instead: | ||
|
@@ -827,6 +828,7 @@ mp.jwt.verify.issuer=${keycloak.url}/realms/quarkus | |
smallrye.jwt.sign.key.location=privateKey.jwk | ||
---- | ||
|
||
[[integration-testing-keycloak]] | ||
=== Keycloak | ||
|
||
If you work with Keycloak and configure `mp.jwt.verify.publickey.location` to point to HTTPS or HTTP based JsonWebKey (JWK) set then you can use the same approach as described in the link:security-openid-connect#integration-testing-keycloak[OpenId Connect Bearer Token Integration testing] `Keycloak` section but only change the `application.properties` to use MP JWT configuration properties instead: | ||
|
@@ -838,6 +840,7 @@ mp.jwt.verify.publickey.location=${keycloak.url}/realms/quarkus/protocol/openid- | |
mp.jwt.verify.issuer=${keycloak.url}/realms/quarkus | ||
---- | ||
|
||
[[integration-testing-public-key]] | ||
=== Local Public Key | ||
|
||
You can use the same approach as described in the link:security-openid-connect#integration-testing[OpenId Connect Bearer Token Integration testing] `Local Public Key` section but only change the `application.properties` to use MP JWT configuration properties instead: | ||
|
@@ -852,9 +855,82 @@ mp.jwt.verify.issuer=${keycloak.url}/realms/quarkus | |
smallrye.jwt.sign.key.location=privateKey.pem | ||
---- | ||
|
||
[[integration-testing-security-annotation]] | ||
=== TestSecurity annotation | ||
|
||
Please see link:security-testing#testing-security[TestingSecurity Annotation] section how to do simple tests with the `TestSecurity` annotation. | ||
Add the following dependency: | ||
[source,xml] | ||
---- | ||
<dependency> | ||
<groupId>io.quarkus</groupId> | ||
<artifactId>quarkus-test-security-jwt</artifactId> | ||
<scope>test</scope> | ||
</dependency> | ||
---- | ||
|
||
and write a test code like this one: | ||
|
||
[source, java] | ||
---- | ||
package io.quarkus.it.keycloak; | ||
import static org.hamcrest.Matchers.is; | ||
import org.junit.jupiter.api.Test; | ||
import io.quarkus.test.common.http.TestHTTPEndpoint; | ||
import io.quarkus.test.junit.QuarkusTest; | ||
import io.quarkus.test.security.SecurityAttribute; | ||
import io.quarkus.test.security.TestSecurity; | ||
import io.restassured.RestAssured; | ||
@QuarkusTest | ||
@TestHTTPEndpoint(ProtectedResource.class) | ||
public class TestSecurityAuthTest { | ||
@Test | ||
@TestSecurity(user = "userJwt", roles = "viewer", attributes = { | ||
@SecurityAttribute(key = "claim.email", value = "[email protected]") | ||
}) | ||
public void testJwtWithDummyUser() { | ||
RestAssured.when().get("test-security-jwt").then() | ||
.body(is("userJwt:viewer:[email protected]")); | ||
} | ||
} | ||
---- | ||
|
||
where `ProtectedResource` class may look like this: | ||
|
||
[source, java] | ||
---- | ||
package io.quarkus.it.keycloak; | ||
import javax.inject.Inject; | ||
import javax.ws.rs.GET; | ||
import javax.ws.rs.Path; | ||
import org.eclipse.microprofile.jwt.JsonWebToken; | ||
import io.quarkus.security.Authenticated; | ||
import io.quarkus.security.identity.SecurityIdentity; | ||
@Path("/web-app") | ||
@Authenticated | ||
public class ProtectedResource { | ||
@Inject | ||
JsonWebToken accessToken; | ||
@GET | ||
@Path("test-security-jwt") | ||
public String testSecurityJwt() { | ||
return accessToken.getName() + ":" + accessToken.getGroups().iterator().next() | ||
+ ":" + accessToken.getClaim("email"); | ||
} | ||
} | ||
---- | ||
|
||
Note that `TestSecurity` `user` property is returned as `JsonWebToken.getName()` and `roles` property - as `JsonWebToken.getGroups()`. Additionally, any `SecurityAttribute` with the key starting from `claim.` will be returned as a token claim value, for example, `claim.email` will support `JsonWebToken.getClaim("email")`, etc. | ||
|
||
[[generate-jwt-tokens]] | ||
== Generate JWT tokens with SmallRye JWT | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,7 @@ | |
|
||
import io.quarkus.test.common.http.TestHTTPEndpoint; | ||
import io.quarkus.test.junit.QuarkusTest; | ||
import io.quarkus.test.security.SecurityAttribute; | ||
import io.quarkus.test.security.TestSecurity; | ||
import io.restassured.RestAssured; | ||
|
||
|
@@ -16,8 +17,17 @@ public class TestSecurityLazyAuthTest { | |
@Test | ||
@TestSecurity(user = "user1", roles = "viewer") | ||
public void testWithDummyUser() { | ||
RestAssured.when().get("sec").then() | ||
RestAssured.when().get("test-security").then() | ||
.body(is("user1")); | ||
} | ||
|
||
@Test | ||
@TestSecurity(user = "userOidc", roles = "viewer", attributes = { | ||
@SecurityAttribute(key = "claim.email", value = "[email protected]") | ||
}) | ||
public void testJwtWithDummyUser() { | ||
RestAssured.when().get("test-security-oidc").then() | ||
.body(is("userOidc:viewer:[email protected]")); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
39 changes: 39 additions & 0 deletions
39
integration-tests/oidc/src/main/java/io/quarkus/it/keycloak/ProtectedJwtResource.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package io.quarkus.it.keycloak; | ||
|
||
import javax.inject.Inject; | ||
import javax.ws.rs.GET; | ||
import javax.ws.rs.Path; | ||
import javax.ws.rs.core.Context; | ||
import javax.ws.rs.core.SecurityContext; | ||
|
||
import org.eclipse.microprofile.jwt.JsonWebToken; | ||
|
||
import io.quarkus.security.Authenticated; | ||
import io.quarkus.security.identity.SecurityIdentity; | ||
|
||
@Path("/web-app") | ||
@Authenticated | ||
public class ProtectedJwtResource { | ||
|
||
@Inject | ||
SecurityIdentity identity; | ||
|
||
@Inject | ||
JsonWebToken accessToken; | ||
|
||
@Context | ||
SecurityContext securityContext; | ||
|
||
@GET | ||
@Path("test-security") | ||
public String testSecurity() { | ||
return securityContext.getUserPrincipal().getName(); | ||
} | ||
|
||
@GET | ||
@Path("test-security-jwt") | ||
public String testSecurityJwt() { | ||
return accessToken.getName() + ":" + accessToken.getGroups().iterator().next() | ||
+ ":" + accessToken.getClaim("email"); | ||
} | ||
} |
33 changes: 33 additions & 0 deletions
33
integration-tests/oidc/src/test/java/io/quarkus/it/keycloak/TestSecurityLazyAuthTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package io.quarkus.it.keycloak; | ||
|
||
import static org.hamcrest.Matchers.is; | ||
|
||
import org.junit.jupiter.api.Test; | ||
|
||
import io.quarkus.test.common.http.TestHTTPEndpoint; | ||
import io.quarkus.test.junit.QuarkusTest; | ||
import io.quarkus.test.security.SecurityAttribute; | ||
import io.quarkus.test.security.TestSecurity; | ||
import io.restassured.RestAssured; | ||
|
||
@QuarkusTest | ||
@TestHTTPEndpoint(ProtectedJwtResource.class) | ||
public class TestSecurityLazyAuthTest { | ||
|
||
@Test | ||
@TestSecurity(user = "user1", roles = "viewer") | ||
public void testWithDummyUser() { | ||
RestAssured.when().get("test-security").then() | ||
.body(is("user1")); | ||
} | ||
|
||
@Test | ||
@TestSecurity(user = "userJwt", roles = "viewer", attributes = { | ||
@SecurityAttribute(key = "claim.email", value = "[email protected]") | ||
}) | ||
public void testJwtWithDummyUser() { | ||
RestAssured.when().get("test-security-jwt").then() | ||
.body(is("userJwt:viewer:[email protected]")); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
39 changes: 39 additions & 0 deletions
39
...lrye-jwt-token-propagation/src/main/java/io/quarkus/it/keycloak/ProtectedJwtResource.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package io.quarkus.it.keycloak; | ||
|
||
import javax.inject.Inject; | ||
import javax.ws.rs.GET; | ||
import javax.ws.rs.Path; | ||
import javax.ws.rs.core.Context; | ||
import javax.ws.rs.core.SecurityContext; | ||
|
||
import org.eclipse.microprofile.jwt.JsonWebToken; | ||
|
||
import io.quarkus.security.Authenticated; | ||
import io.quarkus.security.identity.SecurityIdentity; | ||
|
||
@Path("/web-app") | ||
@Authenticated | ||
public class ProtectedJwtResource { | ||
|
||
@Inject | ||
SecurityIdentity identity; | ||
|
||
@Inject | ||
JsonWebToken accessToken; | ||
|
||
@Context | ||
SecurityContext securityContext; | ||
|
||
@GET | ||
@Path("test-security") | ||
public String testSecurity() { | ||
return securityContext.getUserPrincipal().getName(); | ||
} | ||
|
||
@GET | ||
@Path("test-security-jwt") | ||
public String testSecurityJwt() { | ||
return accessToken.getName() + ":" + accessToken.getGroups().iterator().next() | ||
+ ":" + accessToken.getClaim("email"); | ||
} | ||
} |
Oops, something went wrong.