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

Web Security Expression section of Documentation is obsolete or it does not work #12974

Closed
nightswimmings opened this issue Apr 7, 2023 · 3 comments
Assignees
Labels
in: docs An issue in Documentation or samples type: bug A general bug
Milestone

Comments

@nightswimmings
Copy link

nightswimmings commented Apr 7, 2023

First of all, the following part is obsolete,
https://docs.spring.io/spring-security/reference/servlet/authorization/expression-based.html#el-access-web-path-variables
for .access() method does not support a String anymore. I guess it must be updated to mirror previous section example that uses a WebExpressionAuthorizationManager()

But trying to reproduce it with WebExpressionAuthorizationManager does not work anyway, because the default expression handler is now DefaultHttpSecurityExpressionHandler instead of DefaultWebSecurityExpressionHandler and an exception jumps in with message "EL1057E: No bean resolver registered in the context to resolve access to bean".

But one cannot work it out with something like

WebExpressionAuthorizationManager authManager = new WebExpressionAuthorizationManager("@webSecurity.check(authentication,request)");
authManager.setExpressionHandler(new DefaultWebSecurityExpressionHandler());

because setExpressionHandler expects a SecurityExpressionHandler and DefaultWebSecurityExpressionHandler has FilterInvocation as type instead of RequestAuthorizationContext. the only built-in usabel one is therefore the default DefaultWebSecurityExpressionHandler.

So the whole section needs to be rewritten, and explain the equivalent modern way to achieve the legacy functionality, or statevery clear that SpEL expressions are not supported anymore out-of-the-box

@nightswimmings nightswimmings added status: waiting-for-triage An issue we've not yet triaged type: enhancement A general enhancement labels Apr 7, 2023
@rwinch rwinch self-assigned this Apr 7, 2023
@rwinch
Copy link
Member

rwinch commented Apr 7, 2023

Thank you for the report. You are right that the documentation needs fixed.

In the meantime, hopefully the following can help you and anyone experiencing this problem. SpEL is typically not necessary or preferred (SpEL is fast, but it does add overhead) with the addition of AuthorizationManager. You can use something like this now:

@Component
static class WebSecurity {
	public boolean checkUserId(Supplier<Authentication> authentication, String id) {
			return authentication.get().getName().equals(id);
	}
}

@Bean
public DefaultSecurityFilterChain springSecurityFilter(HttpSecurity http, WebSecurity webSecurity) throws Exception {
	http
		.authorizeHttpRequests(exchange -> exchange
			.requestMatchers("/user/{userId}/**").access((authentication, context) -> {
					String userId = context.getVariables().get("userId");
					boolean granted = webSecurity.checkUserId(authentication, userId);
					return new AuthorizationDecision(granted);
				}
			)
			.anyRequest().authenticated()
		)
		.formLogin(withDefaults());
	return http.build();
}

If you really want to use SpEL you can use something like this:

@Component("webSecurity")
static class WebSecurity {
	public boolean checkUserId(Authentication authentication, String id) {
			return authentication.getName().equals(id);
	}
}

@Bean
public DefaultSecurityFilterChain springSecurityFilter(HttpSecurity http, ApplicationContext context) throws Exception {
	DefaultHttpSecurityExpressionHandler expressionHandler = new DefaultHttpSecurityExpressionHandler();
	expressionHandler.setApplicationContext(context);
	WebExpressionAuthorizationManager authorization = new WebExpressionAuthorizationManager("@webSecurity.checkUserId(authentication,#userId)");
	authorization.setExpressionHandler(expressionHandler);
	http
		.authorizeHttpRequests(exchange -> exchange
			.requestMatchers("/user/{userId}/**").access(authorization)
			.anyRequest().authenticated()
		)
		.formLogin(withDefaults());
	return http.build();
}

@nightswimmings
Copy link
Author

Thank you a lot @rwinch, very useful indeed!

@rwinch rwinch added in: docs An issue in Documentation or samples type: bug A general bug and removed status: waiting-for-triage An issue we've not yet triaged type: enhancement A general enhancement labels Apr 7, 2023
@jzheaux jzheaux assigned jzheaux and unassigned rwinch May 9, 2023
@jzheaux jzheaux added this to the 6.1.0 milestone May 12, 2023
@vinayvishwkarma
Copy link

How can we use it for OAuth2WebSecurityExpressionHandler

sjohnr pushed a commit that referenced this issue Dec 28, 2023
Refactor: Remove two lines that lack proper context due to earlier
deletions/movements. They are no longer relevant and contribute little
to the overall meaning.

Issue gh-12974
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: bug A general bug
Projects
Status: Done
Development

No branches or pull requests

4 participants