Describe the bug When I use Expression-Based Access Control according to the spring security document of 6.0.2 I'm getting following error:


at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:191) ~[spring-security-web-6.0.2.jar:6.0.2]
    .....
    at java.base/java.lang.Thread.run(Thread.java:1589) ~[na:na]
Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1057E: No bean resolver registered in the context to resolve access to bean 'webSecurity'
    at org.springframework.expression.spel.ast.BeanReference.getValueInternal(BeanReference.java:51) ~[spring-expression-6.0.7.jar:6.0.7]
    at org.springframework.expression.spel.ast.CompoundExpression.getValueRef(CompoundExpression.java:55) ~[spring-expression-6.0.7.jar:6.0.7]
    at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:91) ~[spring-expression-6.0.7.jar:6.0.7]
    at org.springframework.expression.spel.ast.SpelNodeImpl.getTypedValue(SpelNodeImpl.java:117) ~[spring-expression-6.0.7.jar:6.0.7]
    at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:309) ~[spring-expression-6.0.7.jar:6.0.7]
    at org.springframework.security.access.expression.ExpressionUtils.evaluateAsBoolean(ExpressionUtils.java:30) ~[spring-security-core-6.0.2.jar:6.0.2]
    ... 71 common frames omitted


**To Reproduce**
Steps to reproduce the behavior.

1.  Configure application.yaml

spring:
  security:
    oauth2:
      resource-server:
        jwt:
          issuer-uri: ${realms.url}


2.  Create and configure spring security in java code

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.access.expression.WebExpressionAuthorizationManager;

@Configuration
public class SecurityConfig {

    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        return http
                .authorizeHttpRequests(authorize ->
                        authorize.requestMatchers("/test/**")
                                .access(new WebExpressionAuthorizationManager("@webSecurity.check(authentication,request)"))
                 )
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and().csrf().disable()
                .oauth2ResourceServer( OAuth2ResourceServerConfigurer::jwt
                )
                .build();
    }
}


3.  Create webSecurity


import jakarta.servlet.http.HttpServletRequest;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;

@Component
public class WebSecurity {
    public boolean check(Authentication authentication, HttpServletRequest request) {
                return true;
    }
}


4.  Create resource controller


import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class RestControllerExample {
    @GetMapping("/test/{id}")
    public String getId( @PathVariable("id") String id){
        return "your id is : " + id;
    }
}


5.  The curl request 

`curl --location 'http://localhost:8080/test/112' --header "Authorization: Bearer $(token)"


Expected behavior The expected behavior will be http 200 response with "your id is : 112" message

Comment From: jzheaux

I think that this is something that needs clarification in the documentation.

If you are referring to a bean, then creating a lambda is preferred. So instead of:

.access(new WebExpressionAuthorizationManager("@webSecurity.check(authentication,request)"))

do:

.access((authentication, context) ->
    new AuthorizationDecision(webSecurity.check(authentication.get(), context.getRequest())))

I will update the documentation accordingly and post an update here.

Comment From: a2z-ice

The solution is working thanks. So are we not able to write expression any more in such case. If it is the case the how will we do the following.

http
    .authorizeHttpRequests(authorize -> authorize
        .requestMatchers("/user/{userId}/**").access("@webSecurity.checkUserId(authentication,#userId)")
        ...
    );

Comment From: alindl

@a2z-ice You'll probably already have found it, but just so the next person doesn't need to search around like I had to:

http
    .authorizeHttpRequests(authorize -> authorize
        .requestMatchers("/user/{userId}/**")
        .access((authentication, context) -> new AuthorizationDecision(
            webSecurity.checkUserId(authentication.get(),
                                    context.getVariables().get("userId"))))
        ...
);