-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
Allow the use of security related annotations to be used as meta-annotations
- Loading branch information
Showing
10 changed files
with
305 additions
and
34 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -918,6 +918,28 @@ public class ProtectedResource { | |
Note that `@TestSecurity` annotation must always be used and its `user` property is returned as `JsonWebToken.getName()` and `roles` property - as `JsonWebToken.getGroups()`. | ||
`@JwtSecurity` annotation is optional and can be used to set the additional token claims. | ||
|
||
[TIP] | ||
==== | ||
`@TestSecurity` and `@JwtSecurity` can be combined in a meta-annotation, for example like so: | ||
[source, java] | ||
---- | ||
@Retention(RetentionPolicy.RUNTIME) | ||
@Target({ ElementType.METHOD }) | ||
@TestSecurity(user = "userOidc", roles = "viewer") | ||
@OidcSecurity(introspectionRequired = true, | ||
introspection = { | ||
@TokenIntrospection(key = "email", value = "[email protected]") | ||
} | ||
) | ||
public @interface TestSecurityMetaAnnotation { | ||
} | ||
---- | ||
This is particularly useful if the same set of security settings needs to be used in multiple test methods. | ||
==== | ||
|
||
=== How to check the errors in the logs | ||
|
||
Please enable `io.quarkus.smallrye.jwt.runtime.auth.MpJwtValidator` `TRACE` level logging to see more details about the token verification or decryption errors: | ||
|
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 |
---|---|---|
|
@@ -1128,6 +1128,28 @@ public class ProtectedResource { | |
|
||
Note that `@TestSecurity` `user` and `roles` attributes are available as `TokenIntrospection` `username` and `scope` properties and you can use `io.quarkus.test.security.oidc.TokenIntrospection` to add the additional introspection response properties such as an `email`, etc. | ||
|
||
[TIP] | ||
==== | ||
`@TestSecurity` and `@OidcSecurity` can be combined in a meta-annotation, for example like so: | ||
[source, java] | ||
---- | ||
@Retention(RetentionPolicy.RUNTIME) | ||
@Target({ ElementType.METHOD }) | ||
@TestSecurity(user = "userOidc", roles = "viewer") | ||
@OidcSecurity(introspectionRequired = true, | ||
introspection = { | ||
@TokenIntrospection(key = "email", value = "[email protected]") | ||
} | ||
) | ||
public @interface TestSecurityMetaAnnotation { | ||
} | ||
---- | ||
This is particularly useful if the same set of security settings needs to be used in multiple test methods. | ||
==== | ||
|
||
=== How to check the errors in the logs | ||
|
||
Please enable `io.quarkus.oidc.runtime.OidcProvider` `TRACE` level logging to see more details about the token verification errors: | ||
|
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 |
---|---|---|
|
@@ -2,6 +2,11 @@ | |
|
||
import static org.hamcrest.Matchers.is; | ||
|
||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
import org.junit.jupiter.api.Test; | ||
|
||
import io.quarkus.test.common.http.TestHTTPEndpoint; | ||
|
@@ -25,6 +30,14 @@ public void testWithDummyUser() { | |
} | ||
|
||
@Test | ||
@TestSecurityMetaAnnotation | ||
public void testJwtWithDummyUser() { | ||
RestAssured.when().get("test-security-oidc").then() | ||
.body(is("userOidc:userOidc:userOidc:viewer:[email protected]:subject:aud")); | ||
} | ||
|
||
@Retention(RetentionPolicy.RUNTIME) | ||
@Target({ ElementType.METHOD }) | ||
@TestSecurity(user = "userOidc", roles = "viewer") | ||
@OidcSecurity(claims = { | ||
@Claim(key = "email", value = "[email protected]") | ||
|
@@ -33,9 +46,8 @@ public void testWithDummyUser() { | |
}, config = { | ||
@ConfigMetadata(key = "audience", value = "aud") | ||
}) | ||
public void testJwtWithDummyUser() { | ||
RestAssured.when().get("test-security-oidc").then() | ||
.body(is("userOidc:userOidc:userOidc:viewer:[email protected]:subject:aud")); | ||
public @interface TestSecurityMetaAnnotation { | ||
|
||
} | ||
|
||
} |
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 |
---|---|---|
|
@@ -2,6 +2,11 @@ | |
|
||
import static org.hamcrest.Matchers.is; | ||
|
||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
import org.junit.jupiter.api.Test; | ||
|
||
import io.quarkus.test.common.http.TestHTTPEndpoint; | ||
|
@@ -17,40 +22,61 @@ | |
public class TestSecurityLazyAuthTest { | ||
|
||
@Test | ||
@TestSecurity(user = "user1", roles = "viewer") | ||
@TestAsUser1Viewer | ||
public void testWithDummyUser() { | ||
RestAssured.when().get("test-security").then() | ||
.body(is("user1")); | ||
} | ||
|
||
@Test | ||
@TestSecurity(user = "user1", roles = "tester") | ||
@TestAsUser1Tester | ||
public void testWithDummyUserForbidden() { | ||
RestAssured.when().get("test-security").then().statusCode(403); | ||
} | ||
|
||
@Test | ||
@TestSecurity(user = "user1", roles = "viewer") | ||
@TestAsUser1Viewer | ||
public void testPostWithDummyUser() { | ||
RestAssured.given().contentType(ContentType.JSON).when().body("{\"name\":\"user1\"}").post("test-security").then() | ||
.body(is("user1:user1")); | ||
} | ||
|
||
@Test | ||
@TestSecurity(user = "user1", roles = "tester") | ||
@TestAsUser1Tester | ||
public void testPostWithDummyUserForbidden() { | ||
RestAssured.given().contentType(ContentType.JSON).when().body("{\"name\":\"user1\"}").post("test-security").then() | ||
.statusCode(403); | ||
} | ||
|
||
@Test | ||
@TestAsUserJwtViewer | ||
public void testJwtGetWithDummyUser() { | ||
RestAssured.when().get("test-security-jwt").then() | ||
.body(is("userJwt:viewer:[email protected]")); | ||
} | ||
|
||
@Retention(RetentionPolicy.RUNTIME) | ||
@Target({ ElementType.METHOD }) | ||
@TestSecurity(user = "user1", roles = "viewer") | ||
public @interface TestAsUser1Viewer { | ||
|
||
} | ||
|
||
@Retention(RetentionPolicy.RUNTIME) | ||
@Target({ ElementType.METHOD }) | ||
@TestSecurity(user = "user1", roles = "tester") | ||
public @interface TestAsUser1Tester { | ||
|
||
} | ||
|
||
@Retention(RetentionPolicy.RUNTIME) | ||
@Target({ ElementType.METHOD }) | ||
@TestSecurity(user = "userJwt", roles = "viewer") | ||
@OidcSecurity(claims = { | ||
@Claim(key = "email", value = "[email protected]") | ||
}) | ||
public void testJwtGetWithDummyUser() { | ||
RestAssured.when().get("test-security-jwt").then() | ||
.body(is("userJwt:viewer:[email protected]")); | ||
public @interface TestAsUserJwtViewer { | ||
|
||
} | ||
|
||
} |
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 |
---|---|---|
|
@@ -2,6 +2,11 @@ | |
|
||
import static org.hamcrest.Matchers.is; | ||
|
||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
import org.junit.jupiter.api.Test; | ||
|
||
import io.quarkus.test.common.http.TestHTTPEndpoint; | ||
|
@@ -17,40 +22,61 @@ | |
public class TestSecurityLazyAuthTest { | ||
|
||
@Test | ||
@TestSecurity(user = "user1", roles = "viewer") | ||
@TestAsUser1Viewer | ||
public void testWithDummyUser() { | ||
RestAssured.when().get("test-security").then() | ||
.body(is("user1:user1:user1")); | ||
} | ||
|
||
@Test | ||
@TestSecurity(user = "user1", roles = "tester") | ||
@TestAsUser1Tester | ||
public void testWithDummyUserForbidden() { | ||
RestAssured.when().get("test-security").then().statusCode(403); | ||
} | ||
|
||
@Test | ||
@TestSecurity(user = "user1", roles = "viewer") | ||
@TestAsUser1Viewer | ||
public void testPostWithDummyUser() { | ||
RestAssured.given().contentType(ContentType.JSON).when().body("{\"name\":\"user1\"}").post("test-security").then() | ||
.body(is("user1:user1")); | ||
} | ||
|
||
@Test | ||
@TestSecurity(user = "user1", roles = "tester") | ||
@TestAsUser1Tester | ||
public void testPostWithDummyUserForbidden() { | ||
RestAssured.given().contentType(ContentType.JSON).when().body("{\"name\":\"user1\"}").post("test-security").then() | ||
.statusCode(403); | ||
} | ||
|
||
@Test | ||
@TestAsUserJwtViewer | ||
public void testJwtGetWithDummyUser() { | ||
RestAssured.when().get("test-security-jwt").then() | ||
.body(is("userJwt:userJwt:userJwt:viewer:[email protected]")); | ||
} | ||
|
||
@Retention(RetentionPolicy.RUNTIME) | ||
@Target({ ElementType.METHOD }) | ||
@TestSecurity(user = "user1", roles = "viewer") | ||
public @interface TestAsUser1Viewer { | ||
|
||
} | ||
|
||
@Retention(RetentionPolicy.RUNTIME) | ||
@Target({ ElementType.METHOD }) | ||
@TestSecurity(user = "user1", roles = "tester") | ||
public @interface TestAsUser1Tester { | ||
|
||
} | ||
|
||
@Retention(RetentionPolicy.RUNTIME) | ||
@Target({ ElementType.METHOD }) | ||
@TestSecurity(user = "userJwt", roles = "viewer") | ||
@JwtSecurity(claims = { | ||
@Claim(key = "email", value = "[email protected]") | ||
}) | ||
public void testJwtGetWithDummyUser() { | ||
RestAssured.when().get("test-security-jwt").then() | ||
.body(is("userJwt:userJwt:userJwt:viewer:[email protected]")); | ||
public @interface TestAsUserJwtViewer { | ||
|
||
} | ||
|
||
} |
23 changes: 23 additions & 0 deletions
23
...-framework/common/src/main/java/io/quarkus/test/util/annotations/AnnotationContainer.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,23 @@ | ||
package io.quarkus.test.util.annotations; | ||
|
||
import java.lang.annotation.Annotation; | ||
import java.lang.reflect.AnnotatedElement; | ||
|
||
public final class AnnotationContainer<A extends Annotation> { | ||
|
||
private final AnnotatedElement element; | ||
private final A annotation; | ||
|
||
public AnnotationContainer(AnnotatedElement element, A annotation) { | ||
this.element = element; | ||
this.annotation = annotation; | ||
} | ||
|
||
public AnnotatedElement getElement() { | ||
return element; | ||
} | ||
|
||
public A getAnnotation() { | ||
return annotation; | ||
} | ||
} |
Oops, something went wrong.