Reputation: 31
I'm using spring boot with spring security
I have rest controller
@RequestMapping("/foo")
public String foo(@RequestBody Foo foo) {
return foo.getBar();
}
And I've added Spring security to this endpoint
.mvcMatchers("/foo").access("@securityChecker.check(#foo)")
Now I have this security checker
@Service
public class SecurityChecker {
public boolean check(Foo foo) {
return foo != null;
}
}
the problem is that Foo is always null.
I'm guessing that it's because Jackson's filter is after Security one. Is there any way to get request body object without injecting HttpRequest object to "check" method and parsing request body? I would like to maybe have security checks after parsing JSON from the request's body.
Here is quick example of what I'm trying to do: https://github.com/kedrigen/spring-security-request-body
Upvotes: 1
Views: 2855
Reputation: 5354
You are missing @RequestBody
(docs):
@PostMapping("/foo") // has to be post mapping
public String foo(@RequestBody Foo foo) {
return foo.getBar();
}
This annotation is used to have the request body read and deserialized into an Object through an HttpMessageConverter
.
You are also missing @EnableWebSecurity
:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter { ... }
But the problem, in general, is you cannot simply do what you are trying to do.
foo
that you expect in your controller has nothing to do with security and security context, so this "@securityChecker.check(#foo)"
won't work.
Consider getting familiar with Referring to Beans in Web Security Expressions documentation.
Example from the docs:
public class WebSecurity {
public boolean check(Authentication authentication, HttpServletRequest request) {
...
}
}
http
.authorizeRequests(authorize -> authorize
.antMatchers("/user/**").access("@webSecurity.check(authentication,request)")
...
)
In a nutshell: this works, because Spring is aware of what authentication
and request
are and they exist in the context. But foo
means nothing to Spring :)
Upvotes: 1