-
Notifications
You must be signed in to change notification settings - Fork 5.9k
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
Comments
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 @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();
} |
Thank you a lot @rwinch, very useful indeed! |
How can we use it for OAuth2WebSecurityExpressionHandler |
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
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
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
The text was updated successfully, but these errors were encountered: