Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expression-Based Access Control do not working as explain in spring security document for 6.0.2 also tried 6.0.5 the issue persist #12928

Closed
a2z-ice opened this issue Mar 26, 2023 · 3 comments
Assignees
Labels
in: docs An issue in Documentation or samples type: enhancement A general enhancement
Milestone

Comments

@a2z-ice
Copy link

a2z-ice commented Mar 26, 2023

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

@a2z-ice a2z-ice added status: waiting-for-triage An issue we've not yet triaged type: bug A general bug labels Mar 26, 2023
@jzheaux
Copy link
Contributor

jzheaux commented Mar 27, 2023

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.

@jzheaux jzheaux self-assigned this Mar 27, 2023
@jzheaux jzheaux added in: docs An issue in Documentation or samples type: enhancement A general enhancement and removed status: waiting-for-triage An issue we've not yet triaged type: bug A general bug labels Mar 27, 2023
@jzheaux jzheaux added this to the 5.8.3 milestone Mar 27, 2023
a2z-ice pushed a commit to a2z-ice/spring-cloud-with-kubernetes that referenced this issue Mar 28, 2023
@a2z-ice
Copy link
Author

a2z-ice commented Mar 28, 2023

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)")
		...
	);

@alindl
Copy link

alindl commented Apr 10, 2024

@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"))))
		...
);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: docs An issue in Documentation or samples type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

3 participants