Skip to content

Commit 4616d52

Browse files
committed
Fix != expression in @PreAuthorize check
Fixes: quarkusio#37526
1 parent 6e48533 commit 4616d52

File tree

5 files changed

+43
-8
lines changed

5 files changed

+43
-8
lines changed

extensions/spring-security/deployment/src/main/java/io/quarkus/spring/security/deployment/SpringSecurityProcessor.java

+7-1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
import io.quarkus.spring.security.runtime.interceptor.SpringPreauthorizeInterceptor;
4949
import io.quarkus.spring.security.runtime.interceptor.SpringSecuredInterceptor;
5050
import io.quarkus.spring.security.runtime.interceptor.SpringSecurityRecorder;
51+
import io.quarkus.spring.security.runtime.interceptor.check.PrincipalNameFromParameterObjectSecurityCheck;
5152
import io.quarkus.spring.security.runtime.interceptor.check.PrincipalNameFromParameterSecurityCheck;
5253

5354
class SpringSecurityProcessor {
@@ -466,13 +467,18 @@ void addSpringPreAuthorizeSecurityCheck(CombinedIndexBuildItem index,
466467
propertyName, index.getIndex(),
467468
part);
468469

470+
PrincipalNameFromParameterObjectSecurityCheck.CheckType checkType = part.contains("==")
471+
? PrincipalNameFromParameterObjectSecurityCheck.CheckType.EQ
472+
: PrincipalNameFromParameterObjectSecurityCheck.CheckType.NEQ;
473+
469474
securityChecks.add(springSecurityRecorder.principalNameFromParameterObjectSecurityCheck(
470475
parameterNameAndIndex.getIndex(),
471476
stringPropertyAccessorData.getMatchingParameterClassInfo().name().toString(),
472477
StringPropertyAccessorGenerator
473478
.getAccessorClassName(
474479
stringPropertyAccessorData.getMatchingParameterClassInfo().name()),
475-
stringPropertyAccessorData.getMatchingParameterFieldInfo().name()));
480+
stringPropertyAccessorData.getMatchingParameterFieldInfo().name(),
481+
checkType));
476482

477483
}
478484
} else if (part.matches(SpringSecurityProcessorUtil.BASIC_BEAN_METHOD_INVOCATION_REGEX)) {

extensions/spring-security/deployment/src/test/java/io/quarkus/spring/security/deployment/SpringPreAuthorizeTest.java

+10
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,16 @@ public void testPrincipalNameFromObject() {
116116
assertSuccess(() -> springComponent.principalNameFromObject(new Person("user")), "user", USER);
117117
}
118118

119+
@Test
120+
public void testPrincipalNameFromObjectIsNot() {
121+
assertFailureFor(() -> springComponent.principalNameFromObjectIsNot(new Person("whatever")),
122+
UnauthorizedException.class,
123+
ANONYMOUS);
124+
assertSuccess(() -> springComponent.principalNameFromObjectIsNot(new Person("whatever")), "whatever", USER);
125+
assertFailureFor(() -> springComponent.principalNameFromObjectIsNot(new Person("user")), ForbiddenException.class,
126+
USER);
127+
}
128+
119129
@Test
120130
public void testNotSecured() {
121131
assertSuccess(() -> springComponent.notSecured(), "notSecured", ANONYMOUS);

extensions/spring-security/deployment/src/test/java/io/quarkus/spring/security/deployment/springapp/SpringComponent.java

+5
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ public String principalNameFromObject(Person person) {
3737
return person.getName();
3838
}
3939

40+
@PreAuthorize("#person.name != authentication.principal.username")
41+
public String principalNameFromObjectIsNot(Person person) {
42+
return person.getName();
43+
}
44+
4045
public String notSecured() {
4146
return "notSecured";
4247
}

extensions/spring-security/runtime/src/main/java/io/quarkus/spring/security/runtime/interceptor/SpringSecurityRecorder.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,9 @@ public SecurityCheck fromGeneratedClass(String generatedClassName) {
7070
}
7171

7272
public SecurityCheck principalNameFromParameterObjectSecurityCheck(int index, String expectedParameterClass,
73-
String stringPropertyAccessorClass, String propertyName) {
73+
String stringPropertyAccessorClass, String propertyName,
74+
PrincipalNameFromParameterObjectSecurityCheck.CheckType checkType) {
7475
return PrincipalNameFromParameterObjectSecurityCheck.of(index, expectedParameterClass, stringPropertyAccessorClass,
75-
propertyName);
76+
propertyName, checkType);
7677
}
7778
}

extensions/spring-security/runtime/src/main/java/io/quarkus/spring/security/runtime/interceptor/check/PrincipalNameFromParameterObjectSecurityCheck.java

+18-5
Original file line numberDiff line numberDiff line change
@@ -23,22 +23,24 @@ public class PrincipalNameFromParameterObjectSecurityCheck implements SecurityCh
2323
private final Class<?> expectedParameterClass;
2424
private final Class<? extends StringPropertyAccessor> stringPropertyAccessorClass;
2525
private final String propertyName;
26+
private final CheckType checkType;
2627

2728
private PrincipalNameFromParameterObjectSecurityCheck(int index, String expectedParameterClass,
28-
String stringPropertyAccessorClass, String propertyName) throws ClassNotFoundException {
29+
String stringPropertyAccessorClass, String propertyName, CheckType checkType) throws ClassNotFoundException {
2930
this.index = index;
3031
this.expectedParameterClass = Class.forName(expectedParameterClass, false,
3132
Thread.currentThread().getContextClassLoader());
3233
this.stringPropertyAccessorClass = (Class<? extends StringPropertyAccessor>) Class.forName(stringPropertyAccessorClass,
3334
false, Thread.currentThread().getContextClassLoader());
3435
this.propertyName = propertyName;
36+
this.checkType = checkType;
3537
}
3638

3739
public static PrincipalNameFromParameterObjectSecurityCheck of(int index, String expectedParameterClass,
38-
String stringPropertyAccessorClass, String propertyName) {
40+
String stringPropertyAccessorClass, String propertyName, CheckType checkType) {
3941
try {
4042
return new PrincipalNameFromParameterObjectSecurityCheck(index, expectedParameterClass, stringPropertyAccessorClass,
41-
propertyName);
43+
propertyName, checkType);
4244
} catch (ClassNotFoundException e) {
4345
throw new RuntimeException(e);
4446
}
@@ -70,8 +72,14 @@ private void doApply(SecurityIdentity identity, Object[] parameters, String clas
7072
}
7173

7274
String name = identity.getPrincipal().getName();
73-
if (!name.equals(parameterValueStr)) {
74-
throw new ForbiddenException();
75+
if (checkType == CheckType.EQ) {
76+
if (!name.equals(parameterValueStr)) {
77+
throw new ForbiddenException();
78+
}
79+
} else if (checkType == CheckType.NEQ) {
80+
if (name.equals(parameterValueStr)) {
81+
throw new ForbiddenException();
82+
}
7583
}
7684
}
7785

@@ -84,4 +92,9 @@ private IllegalStateException genericNotApplicableException(String className, St
8492
"PrincipalNameFromParameterObjectSecurityCheck with index " + index + " cannot be applied to '" + className
8593
+ "#" + methodName + "'");
8694
}
95+
96+
public enum CheckType {
97+
EQ,
98+
NEQ
99+
}
87100
}

0 commit comments

Comments
 (0)