Skip to content
Permalink

Comparing changes

This is a direct comparison between two commits made in this repository or its related repositories. View the default comparison for this range or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: spring-projects/spring-security
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 1de2f3680c3658d5b308a4ca2d541f3fe788e36c
Choose a base ref
..
head repository: spring-projects/spring-security
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: b21850a1345841072b02b4ac7c5ba6191b1ccec3
Choose a head ref
Original file line number Diff line number Diff line change
@@ -22,7 +22,6 @@

import jakarta.servlet.Filter;

import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
@@ -66,20 +65,16 @@
* @see WebSecurity
*/
@Configuration(proxyBeanMethods = false)
public class WebSecurityConfiguration implements ImportAware, BeanClassLoaderAware {
public class WebSecurityConfiguration implements ImportAware {

private WebSecurity webSecurity;

private Boolean debugEnabled;

private List<SecurityConfigurer<Filter, WebSecurity>> webSecurityConfigurers;

private List<SecurityFilterChain> securityFilterChains = Collections.emptyList();

private List<WebSecurityCustomizer> webSecurityCustomizers = Collections.emptyList();

private ClassLoader beanClassLoader;

@Bean
public static DelegatingApplicationListener delegatingApplicationListener() {
return new DelegatingApplicationListener();
@@ -163,7 +158,6 @@ public void setFilterChainProxySecurityConfigurer(ObjectPostProcessor<Object> ob
for (SecurityConfigurer<Filter, WebSecurity> webSecurityConfigurer : webSecurityConfigurers) {
this.webSecurity.apply(webSecurityConfigurer);
}
this.webSecurityConfigurers = webSecurityConfigurers;
}

@Autowired(required = false)
@@ -192,11 +186,6 @@ public void setImportMetadata(AnnotationMetadata importMetadata) {
}
}

@Override
public void setBeanClassLoader(ClassLoader classLoader) {
this.beanClassLoader = classLoader;
}

/**
* A custom version of the Spring provided AnnotationAwareOrderComparator that uses
* {@link AnnotationUtils#findAnnotation(Class, Class)} to look on super class
Original file line number Diff line number Diff line change
@@ -331,7 +331,8 @@ public void loadConfigWhenTwoSecurityFilterChainsPresentAndSecondWithAnyRequestT
@Test
public void avoidUnnecessaryHttpSecurityInstantiationWhenProvideOneSecurityFilterChain() {
this.spring.register(SecurityFilterChainConfig.class).autowire();
assertThat(this.spring.getContext().getBean(CustomBeanPostProcessor.class).instantiationCount).isEqualTo(1);
assertThat(this.spring.getContext().getBean(CountHttpSecurityBeanPostProcessor.class).instantiationCount)
.isEqualTo(1);
}

private void assertAnotherUserPermission(WebInvocationPrivilegeEvaluator privilegeEvaluator) {
@@ -357,7 +358,7 @@ private void assertUserPermissions(WebInvocationPrivilegeEvaluator privilegeEval

@Configuration
@EnableWebSecurity
@Import(CustomBeanPostProcessor.class)
@Import(CountHttpSecurityBeanPostProcessor.class)
static class SecurityFilterChainConfig {

@Bean
@@ -367,7 +368,7 @@ SecurityFilterChain filterChain(HttpSecurity http) throws Exception {

}

static class CustomBeanPostProcessor implements BeanPostProcessor {
static class CountHttpSecurityBeanPostProcessor implements BeanPostProcessor {

int instantiationCount = 0;

28 changes: 14 additions & 14 deletions docs/modules/ROOT/pages/servlet/authorization/method-security.adoc
Original file line number Diff line number Diff line change
@@ -108,7 +108,7 @@ Kotlin::
open class MyCustomerService {
@PreAuthorize("hasAuthority('permission:read')")
@PostAuthorize("returnObject.owner == authentication.name")
fun readCustomer(val id: String): Customer { ... }
fun readCustomer(id: String): Customer { ... }
}
----
======
@@ -338,7 +338,7 @@ Kotlin::
@Component
open class BankService {
@PreAuthorize("hasRole('ADMIN')")
fun readAccount(val id: Long): Account {
fun readAccount(id: Long): Account {
// ... is only invoked if the `Authentication` has the `ROLE_ADMIN` authority
}
}
@@ -426,7 +426,7 @@ Kotlin::
@Component
open class BankService {
@PostAuthorize("returnObject.owner == authentication.name")
fun readAccount(val id: Long): Account {
fun readAccount(id: Long): Account {
// ... is only returned if the `Account` belongs to the logged in user
}
}
@@ -536,7 +536,7 @@ Kotlin::
@Component
open class BankService {
@RequireOwnership
fun readAccount(val id: Long): Account {
fun readAccount(id: Long): Account {
// ... is only returned if the `Account` belongs to the logged in user
}
}
@@ -993,7 +993,7 @@ Kotlin::
@Component
open class BankService {
@IsAdmin
fun readAccount(val id: Long): Account {
fun readAccount(id: Long): Account {
// ... is only returned if the `Account` belongs to the logged in user
}
}
@@ -1084,7 +1084,7 @@ Kotlin::
@Component
open class BankService {
@HasRole("ADMIN")
fun readAccount(val id: Long): Account {
fun readAccount(id: Long): Account {
// ... is only returned if the `Account` belongs to the logged in user
}
}
@@ -1144,7 +1144,7 @@ Kotlin::
@Component
open class BankService {
@HasAnyRole(roles = arrayOf("'USER'", "'ADMIN'"))
fun readAccount(val id: Long): Account {
fun readAccount(id: Long): Account {
// ... is only returned if the `Account` belongs to the logged in user
}
}
@@ -1271,7 +1271,7 @@ Kotlin::
----
@Component("authz")
open class AuthorizationLogic {
fun decide(val operations: MethodSecurityExpressionOperations): boolean {
fun decide(operations: MethodSecurityExpressionOperations): boolean {
// ... authorization logic
}
}
@@ -1342,7 +1342,7 @@ Kotlin::
----
@Component("authz")
open class AuthorizationLogic {
fun decide(val operations: MethodSecurityExpressionOperations): AuthorizationDecision {
fun decide(operations: MethodSecurityExpressionOperations): AuthorizationDecision {
// ... authorization logic
return MyAuthorizationDecision(false, details)
}
@@ -1435,13 +1435,13 @@ Kotlin::
class MethodSecurityConfig {
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
fun preAuthorize(val manager: MyAuthorizationManager) : Advisor {
fun preAuthorize(manager: MyAuthorizationManager) : Advisor {
return AuthorizationManagerBeforeMethodInterceptor.preAuthorize(manager)
}
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
fun postAuthorize(val manager: MyAuthorizationManager) : Advisor {
fun postAuthorize(manager: MyAuthorizationManager) : Advisor {
return AuthorizationManagerAfterMethodInterceptor.postAuthorize(manager)
}
}
@@ -1501,7 +1501,7 @@ Kotlin::
----
companion object {
@Bean
fun methodSecurityExpressionHandler(val roleHierarchy: RoleHierarchy) : MethodSecurityExpressionHandler {
fun methodSecurityExpressionHandler(roleHierarchy: RoleHierarchy) : MethodSecurityExpressionHandler {
val handler = DefaultMethodSecurityExpressionHandler()
handler.setRoleHierarchy(roleHierarchy)
return handler
@@ -3236,7 +3236,7 @@ Kotlin::
[source,kotlin,role="secondary"]
----
class MyAuthorizer {
fun isAdmin(val root: MethodSecurityExpressionOperations): boolean {
fun isAdmin(root: MethodSecurityExpressionOperations): boolean {
val decision = root.hasAuthority("ADMIN");
// custom work ...
return decision;
@@ -3295,7 +3295,7 @@ Kotlin::
----
@Component
class MyExpressionHandler: DefaultMethodSecurityExpressionHandler {
override fun createEvaluationContext(val authentication: Supplier<Authentication>,
override fun createEvaluationContext(authentication: Supplier<Authentication>,
val mi: MethodInvocation): EvaluationContext {
val context = super.createEvaluationContext(authentication, mi) as StandardEvaluationContext
val delegate = context.getRootObject().getValue() as MethodSecurityExpressionOperations