问题
How can I get _csrf object (?!) in spring controller? I've configured Spring Security and can get ${_csrf} request attribute in jsp files. I've tried:
CsrfToken _csrf = (CsrfToken) session.getAttribute("CsrfToken");
CsrfToken _csrf = (CsrfToken) session.getAttribute("_csrf");
the result is null;
Thanks in advance!
回答1:
In debug I saw a session attribute with a key "org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository.CSRF_TOKEN". I viewed the HttpSessionCsrfTokenRepository class. It has a method for loading token from incoming HttpServletRequest object.
Finally this worked for me:
CsrfToken token = new HttpSessionCsrfTokenRepository().loadToken(request);
I will be grateful if someone explains me how this works.
回答2:
Try:
CsrfToken token = (CsrfToken) session.getAttribute(CsrfToken.class.getName());
回答3:
To access the CSRF token in a Spring controller you can simply do this:
@Controller
public class FooController {
@RequestMapping("/foo")
public void foo(CsrfToken token) {
// Do whatever with token
}
}
Spring will automatically detect that you want the token, based on the type of the parameter, and inject it into your method.
This works since at least Spring Security 5.0 and if you are using Spring Boot or have the @EnableWebSecurity
annotation in your configuration.
Documentation
回答4:
I think in your earlier attempts, you were mixing up the CSRF parameter name with the session attribute name, and also trying CsrfToken.class.getName()
which may or may not have been used in earlier versions. So simply, you had the right idea but the wrong key.
If you look at the source code for HttpSessionCsrfTokenRepository
, you'll see it defines the following defaults:
private String parameterName = DEFAULT_CSRF_PARAMETER_NAME;
private String headerName = DEFAULT_CSRF_HEADER_NAME;
private String sessionAttributeName = DEFAULT_CSRF_TOKEN_ATTR_NAME;
The first one is the parameter name for when the token comes as a POST parameter, the second is the header name for when it comes in the request header, and the third is the key for storing it in the session. The method loadToken
doesn't actually get the token from the request object - it gets the session object from the request and then looks up the token, which it earlier stored with the key defined by sessionAttributeName
.
回答5:
This also works if you want to get it directly from the session
CsrfToken token = (CsrfToken) session.getAttribute("org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository.CSRF_TOKEN");
来源:https://stackoverflow.com/questions/36339552/get-csrf-in-spring-controller