Skip to content

Commit cf559ab

Browse files
evgeniychebanSteve Riesenberg
authored andcommitted
Some Security Expressions cause NPE when used within Query annotation
Added trustResolver, roleHierarchy, permissionEvaluator, defaultRolePrefix fields to SecurityEvaluationContextExtension. Closes gh-11196 Closes gh-11290
1 parent 649428b commit cf559ab

File tree

2 files changed

+37
-3
lines changed

2 files changed

+37
-3
lines changed

data/src/main/java/org/springframework/security/data/repository/query/SecurityEvaluationContextExtension.java

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2019 the original author or authors.
2+
* Copyright 2002-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -17,7 +17,13 @@
1717
package org.springframework.security.data.repository.query;
1818

1919
import org.springframework.data.spel.spi.EvaluationContextExtension;
20+
import org.springframework.security.access.PermissionEvaluator;
21+
import org.springframework.security.access.expression.DenyAllPermissionEvaluator;
2022
import org.springframework.security.access.expression.SecurityExpressionRoot;
23+
import org.springframework.security.access.hierarchicalroles.NullRoleHierarchy;
24+
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
25+
import org.springframework.security.authentication.AuthenticationTrustResolver;
26+
import org.springframework.security.authentication.AuthenticationTrustResolverImpl;
2127
import org.springframework.security.core.Authentication;
2228
import org.springframework.security.core.context.SecurityContext;
2329
import org.springframework.security.core.context.SecurityContextHolder;
@@ -77,12 +83,21 @@
7783
* it.
7884
*
7985
* @author Rob Winch
86+
* @author Evgeniy Cheban
8087
* @since 4.0
8188
*/
8289
public class SecurityEvaluationContextExtension implements EvaluationContextExtension {
8390

8491
private Authentication authentication;
8592

93+
private AuthenticationTrustResolver trustResolver = new AuthenticationTrustResolverImpl();
94+
95+
private RoleHierarchy roleHierarchy = new NullRoleHierarchy();
96+
97+
private PermissionEvaluator permissionEvaluator = new DenyAllPermissionEvaluator();
98+
99+
private String defaultRolePrefix = "ROLE_";
100+
86101
/**
87102
* Creates a new instance that uses the current {@link Authentication} found on the
88103
* {@link org.springframework.security.core.context.SecurityContextHolder}.
@@ -106,8 +121,13 @@ public String getExtensionId() {
106121
@Override
107122
public SecurityExpressionRoot getRootObject() {
108123
Authentication authentication = getAuthentication();
109-
return new SecurityExpressionRoot(authentication) {
124+
SecurityExpressionRoot root = new SecurityExpressionRoot(authentication) {
110125
};
126+
root.setTrustResolver(this.trustResolver);
127+
root.setRoleHierarchy(this.roleHierarchy);
128+
root.setPermissionEvaluator(this.permissionEvaluator);
129+
root.setDefaultRolePrefix(this.defaultRolePrefix);
130+
return root;
111131
}
112132

113133
private Authentication getAuthentication() {

data/src/test/java/org/springframework/security/data/repository/query/SecurityEvaluationContextExtensionTests.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -20,7 +20,10 @@
2020
import org.junit.jupiter.api.BeforeEach;
2121
import org.junit.jupiter.api.Test;
2222

23+
import org.springframework.security.access.expression.DenyAllPermissionEvaluator;
2324
import org.springframework.security.access.expression.SecurityExpressionRoot;
25+
import org.springframework.security.access.hierarchicalroles.NullRoleHierarchy;
26+
import org.springframework.security.authentication.AuthenticationTrustResolverImpl;
2427
import org.springframework.security.authentication.TestingAuthenticationToken;
2528
import org.springframework.security.core.context.SecurityContextHolder;
2629

@@ -69,6 +72,17 @@ public void getRootObjectExplicitAuthentication() {
6972
assertThat(getRoot().getAuthentication()).isSameAs(explicit);
7073
}
7174

75+
@Test
76+
public void getRootObjectWhenAdditionalFieldsNotSetThenVerifyDefaults() {
77+
TestingAuthenticationToken explicit = new TestingAuthenticationToken("explicit", "password", "ROLE_EXPLICIT");
78+
this.securityExtension = new SecurityEvaluationContextExtension(explicit);
79+
SecurityExpressionRoot root = getRoot();
80+
assertThat(root).extracting("trustResolver").isInstanceOf(AuthenticationTrustResolverImpl.class);
81+
assertThat(root).extracting("roleHierarchy").isInstanceOf(NullRoleHierarchy.class);
82+
assertThat(root).extracting("permissionEvaluator").isInstanceOf(DenyAllPermissionEvaluator.class);
83+
assertThat(root).extracting("defaultRolePrefix").isEqualTo("ROLE_");
84+
}
85+
7286
private SecurityExpressionRoot getRoot() {
7387
return this.securityExtension.getRootObject();
7488
}

0 commit comments

Comments
 (0)