parent
3a1692f3c3
commit
eedcec9d5c
|
@ -0,0 +1,42 @@
|
|||
apply plugin: 'io.spring.convention.spring-module'
|
||||
|
||||
dependencies {
|
||||
management platform(project(":spring-security-dependencies"))
|
||||
api project(':spring-security-crypto')
|
||||
api project(':spring-security-core')
|
||||
api 'org.springframework:spring-aop'
|
||||
api 'org.springframework:spring-beans'
|
||||
api 'org.springframework:spring-context'
|
||||
api 'org.springframework:spring-core'
|
||||
api 'org.springframework:spring-expression'
|
||||
api 'io.micrometer:micrometer-observation'
|
||||
|
||||
optional 'com.fasterxml.jackson.core:jackson-databind'
|
||||
optional 'io.micrometer:context-propagation'
|
||||
optional 'io.projectreactor:reactor-core'
|
||||
optional 'jakarta.annotation:jakarta.annotation-api'
|
||||
optional 'org.aspectj:aspectjrt'
|
||||
optional 'org.springframework:spring-jdbc'
|
||||
optional 'org.springframework:spring-tx'
|
||||
optional 'org.jetbrains.kotlinx:kotlinx-coroutines-reactor'
|
||||
|
||||
testImplementation 'commons-collections:commons-collections'
|
||||
testImplementation 'io.projectreactor:reactor-test'
|
||||
testImplementation "org.assertj:assertj-core"
|
||||
testImplementation "org.junit.jupiter:junit-jupiter-api"
|
||||
testImplementation "org.junit.jupiter:junit-jupiter-params"
|
||||
testImplementation "org.junit.jupiter:junit-jupiter-engine"
|
||||
testImplementation "org.mockito:mockito-core"
|
||||
testImplementation "org.mockito:mockito-junit-jupiter"
|
||||
testImplementation "org.springframework:spring-core-test"
|
||||
testImplementation "org.springframework:spring-test"
|
||||
testImplementation 'org.skyscreamer:jsonassert'
|
||||
testImplementation 'org.springframework:spring-test'
|
||||
testImplementation 'org.jetbrains.kotlin:kotlin-reflect'
|
||||
testImplementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'
|
||||
testImplementation 'io.mockk:mockk'
|
||||
|
||||
testRuntimeOnly 'org.hsqldb:hsqldb'
|
||||
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright 2004-present the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Support for JSR-250 and Spring Security {@code @Secured} annotations.
|
||||
*/
|
||||
@NullMarked
|
||||
package org.springframework.security.access.annotation;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright 2004-present the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implementation of expression-based method security.
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
@NullMarked
|
||||
package org.springframework.security.access.expression.method;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright 2004-present the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Core access-control related code, including security metadata related classes,
|
||||
* interception code, access control annotations, EL support and voter-based
|
||||
* implementations of the central
|
||||
* {@link org.springframework.security.access.AccessDecisionManager AccessDecisionManager}
|
||||
* interface.
|
||||
*/
|
||||
@NullMarked
|
||||
package org.springframework.security.access;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright 2004-present the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Contains the infrastructure classes for handling the {@code @PreAuthorize},
|
||||
* {@code @PreFilter}, {@code @PostAuthorize} and {@code @PostFilter} annotations.
|
||||
* <p>
|
||||
* Other than the annotations themselves, the classes should be regarded as for internal
|
||||
* framework use and are liable to change without notice.
|
||||
*/
|
||||
@NullMarked
|
||||
package org.springframework.security.access.prepost;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.security.access;
|
||||
|
||||
/**
|
||||
* Represents the interface of a secured object.
|
||||
*
|
||||
* @author Ben Alex
|
||||
*/
|
||||
public interface ITargetObject {
|
||||
|
||||
Integer computeHashCode(String input);
|
||||
|
||||
int countLength(String input);
|
||||
|
||||
String makeLowerCase(String input);
|
||||
|
||||
String makeUpperCase(String input);
|
||||
|
||||
String publicMakeLowerCase(String input);
|
||||
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.security.access;
|
||||
|
||||
/**
|
||||
* Simply extends {@link TargetObject} so we have a different object to put configuration
|
||||
* attributes against.
|
||||
* <P>
|
||||
* There is no different behaviour. We have to define each method so that
|
||||
* <code>Class.getMethod(methodName, args)</code> returns a <code>Method</code>
|
||||
* referencing this class rather than the parent class.
|
||||
* </p>
|
||||
* <P>
|
||||
* We need to implement <code>ITargetObject</code> again because the
|
||||
* <code>MethodDefinitionAttributes</code> only locates attributes on interfaces
|
||||
* explicitly defined by the intercepted class (not the interfaces defined by its parent
|
||||
* class or classes).
|
||||
* </p>
|
||||
*
|
||||
* @author Ben Alex
|
||||
*/
|
||||
public class OtherTargetObject extends TargetObject implements ITargetObject {
|
||||
|
||||
@Override
|
||||
public String makeLowerCase(String input) {
|
||||
return super.makeLowerCase(input);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String makeUpperCase(String input) {
|
||||
return super.makeUpperCase(input);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String publicMakeLowerCase(String input) {
|
||||
return super.publicMakeLowerCase(input);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.security.access;
|
||||
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
|
||||
/**
|
||||
* Represents a secured object.
|
||||
*
|
||||
* @author Ben Alex
|
||||
*/
|
||||
public class TargetObject implements ITargetObject {
|
||||
|
||||
@Override
|
||||
public Integer computeHashCode(String input) {
|
||||
return input.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countLength(String input) {
|
||||
return input.length();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the lowercase string, followed by security environment information.
|
||||
* @param input the message to make lowercase
|
||||
* @return the lowercase message, a space, the <code>Authentication</code> class that
|
||||
* was on the <code>SecurityContext</code> at the time of method invocation, and a
|
||||
* boolean indicating if the <code>Authentication</code> object is authenticated or
|
||||
* not
|
||||
*/
|
||||
@Override
|
||||
public String makeLowerCase(String input) {
|
||||
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
|
||||
if (auth == null) {
|
||||
return input.toLowerCase() + " Authentication empty";
|
||||
}
|
||||
else {
|
||||
return input.toLowerCase() + " " + auth.getClass().getName() + " " + auth.isAuthenticated();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the uppercase string, followed by security environment information.
|
||||
* @param input the message to make uppercase
|
||||
* @return the uppercase message, a space, the <code>Authentication</code> class that
|
||||
* was on the <code>SecurityContext</code> at the time of method invocation, and a
|
||||
* boolean indicating if the <code>Authentication</code> object is authenticated or
|
||||
* not
|
||||
*/
|
||||
@Override
|
||||
public String makeUpperCase(String input) {
|
||||
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
|
||||
return input.toUpperCase() + " " + auth.getClass().getName() + " " + auth.isAuthenticated();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delegates through to the {@link #makeLowerCase(String)} method.
|
||||
* @param input the message to be made lower-case
|
||||
*/
|
||||
@Override
|
||||
public String publicMakeLowerCase(String input) {
|
||||
return this.makeLowerCase(input);
|
||||
}
|
||||
|
||||
}
|
|
@ -39,8 +39,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||
import static org.assertj.core.api.Assertions.fail;
|
||||
|
||||
/**
|
||||
* Tests for
|
||||
* {@link org.springframework.security.access.annotation.SecuredAnnotationSecurityMetadataSource}
|
||||
* Tests for {@link SecuredAnnotationSecurityMetadataSource}
|
||||
*
|
||||
* @author Mark St.Godard
|
||||
* @author Joe Scalise
|
|
@ -17,6 +17,7 @@
|
|||
package org.springframework.security.access.expression.method;
|
||||
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
@ -28,7 +29,6 @@ import org.springframework.security.access.expression.ExpressionUtils;
|
|||
import org.springframework.security.authentication.AuthenticationTrustResolver;
|
||||
import org.springframework.security.core.Authentication;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
|
@ -65,19 +65,19 @@ public class MethodSecurityExpressionRootTests {
|
|||
public void canCallMethodsOnVariables() {
|
||||
this.ctx.setVariable("var", "somestring");
|
||||
Expression e = this.parser.parseExpression("#var.length() == 10");
|
||||
assertThat(ExpressionUtils.evaluateAsBoolean(e, this.ctx)).isTrue();
|
||||
Assertions.assertThat(ExpressionUtils.evaluateAsBoolean(e, this.ctx)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isAnonymousReturnsTrueIfTrustResolverReportsAnonymous() {
|
||||
given(this.trustResolver.isAnonymous(this.user)).willReturn(true);
|
||||
assertThat(this.root.isAnonymous()).isTrue();
|
||||
Assertions.assertThat(this.root.isAnonymous()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isAnonymousReturnsFalseIfTrustResolverReportsNonAnonymous() {
|
||||
given(this.trustResolver.isAnonymous(this.user)).willReturn(false);
|
||||
assertThat(this.root.isAnonymous()).isFalse();
|
||||
Assertions.assertThat(this.root.isAnonymous()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -87,7 +87,7 @@ public class MethodSecurityExpressionRootTests {
|
|||
this.ctx.setVariable("domainObject", dummyDomainObject);
|
||||
this.root.setPermissionEvaluator(pe);
|
||||
given(pe.hasPermission(this.user, dummyDomainObject, "ignored")).willReturn(false);
|
||||
assertThat(this.root.hasPermission(dummyDomainObject, "ignored")).isFalse();
|
||||
Assertions.assertThat(this.root.hasPermission(dummyDomainObject, "ignored")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -97,7 +97,7 @@ public class MethodSecurityExpressionRootTests {
|
|||
this.ctx.setVariable("domainObject", dummyDomainObject);
|
||||
this.root.setPermissionEvaluator(pe);
|
||||
given(pe.hasPermission(this.user, dummyDomainObject, "ignored")).willReturn(true);
|
||||
assertThat(this.root.hasPermission(dummyDomainObject, "ignored")).isTrue();
|
||||
Assertions.assertThat(this.root.hasPermission(dummyDomainObject, "ignored")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -109,13 +109,13 @@ public class MethodSecurityExpressionRootTests {
|
|||
given(pe.hasPermission(eq(this.user), eq(dummyDomainObject), any(Integer.class))).willReturn(true, true, false);
|
||||
Expression e = this.parser.parseExpression("hasPermission(#domainObject, 0xA)");
|
||||
// evaluator returns true
|
||||
assertThat(ExpressionUtils.evaluateAsBoolean(e, this.ctx)).isTrue();
|
||||
Assertions.assertThat(ExpressionUtils.evaluateAsBoolean(e, this.ctx)).isTrue();
|
||||
e = this.parser.parseExpression("hasPermission(#domainObject, 10)");
|
||||
// evaluator returns true
|
||||
assertThat(ExpressionUtils.evaluateAsBoolean(e, this.ctx)).isTrue();
|
||||
Assertions.assertThat(ExpressionUtils.evaluateAsBoolean(e, this.ctx)).isTrue();
|
||||
e = this.parser.parseExpression("hasPermission(#domainObject, 0xFF)");
|
||||
// evaluator returns false, make sure return value matches
|
||||
assertThat(ExpressionUtils.evaluateAsBoolean(e, this.ctx)).isFalse();
|
||||
Assertions.assertThat(ExpressionUtils.evaluateAsBoolean(e, this.ctx)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -132,11 +132,11 @@ public class MethodSecurityExpressionRootTests {
|
|||
given(pe.hasPermission(this.user, targetObject, i)).willReturn(true, false);
|
||||
given(pe.hasPermission(this.user, "x", i)).willReturn(true);
|
||||
Expression e = this.parser.parseExpression("hasPermission(this, 2)");
|
||||
assertThat(ExpressionUtils.evaluateAsBoolean(e, this.ctx)).isTrue();
|
||||
Assertions.assertThat(ExpressionUtils.evaluateAsBoolean(e, this.ctx)).isTrue();
|
||||
e = this.parser.parseExpression("hasPermission(this, 2)");
|
||||
assertThat(ExpressionUtils.evaluateAsBoolean(e, this.ctx)).isFalse();
|
||||
Assertions.assertThat(ExpressionUtils.evaluateAsBoolean(e, this.ctx)).isFalse();
|
||||
e = this.parser.parseExpression("hasPermission(this.x, 2)");
|
||||
assertThat(ExpressionUtils.evaluateAsBoolean(e, this.ctx)).isTrue();
|
||||
Assertions.assertThat(ExpressionUtils.evaluateAsBoolean(e, this.ctx)).isTrue();
|
||||
}
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue