Java 获取弹簧控制器中的csrf
如何在spring控制器中获取_csrf对象(?)?我已经配置了Spring安全性,可以在jsp文件中获取${u csrf}请求属性。 我试过:Java 获取弹簧控制器中的csrf,java,spring,spring-mvc,spring-security,csrf,Java,Spring,Spring Mvc,Spring Security,Csrf,如何在spring控制器中获取_csrf对象(?)?我已经配置了Spring安全性,可以在jsp文件中获取${u csrf}请求属性。 我试过: CsrfToken _csrf = (CsrfToken) session.getAttribute("CsrfToken"); CsrfToken _csrf = (CsrfToken) session.getAttribute("_csrf"); 结果为空 提前谢谢 试试看: CsrfToken token = (CsrfToken) sessi
CsrfToken _csrf = (CsrfToken) session.getAttribute("CsrfToken");
CsrfToken _csrf = (CsrfToken) session.getAttribute("_csrf");
结果为空
提前谢谢 试试看:
CsrfToken token = (CsrfToken) session.getAttribute(CsrfToken.class.getName());
在debug中,我看到了一个会话属性,其密钥为“org.springframework.security.web.csrf.httpsessionsrftokenrepository.csrf_令牌”。我看了这堂课。它有一个从传入的HttpServletRequest对象加载令牌的方法 最后,这对我起了作用:
CsrfToken token = new HttpSessionCsrfTokenRepository().loadToken(request);
如果有人向我解释这是如何工作的,我将不胜感激。我认为在您之前的尝试中,您将CSRF参数名称与会话属性名称混淆,并且尝试了
CsrfToken.class.getName()
,这可能在早期版本中使用过,也可能没有。简单地说,你的想法是对的,但钥匙是错的。
如果查看httpsessionsrftokenrepository
的源代码,您将看到它定义了以下默认值:
private String parameterName = DEFAULT_CSRF_PARAMETER_NAME;
private String headerName = DEFAULT_CSRF_HEADER_NAME;
private String sessionAttributeName = DEFAULT_CSRF_TOKEN_ATTR_NAME;
第一个是当令牌作为POST参数出现时的参数名,第二个是当它出现在请求头中时的头名称,第三个是用于将其存储在会话中的密钥。方法
loadToken
实际上并没有从请求对象获取令牌-它从请求获取会话对象,然后查找令牌,该令牌先前使用由sessionAttributeName
定义的键存储。如果您想直接从会话获取该令牌,这同样有效
CsrfToken token = (CsrfToken) session.getAttribute("org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository.CSRF_TOKEN");
要访问Spring控制器中的CSRF令牌,只需执行以下操作:
@Controller
public class FooController {
@RequestMapping("/foo")
public void foo(CsrfToken token) {
// Do whatever with token
}
}
Spring将根据参数的类型自动检测您是否需要令牌,并将其注入到您的方法中
至少从Spring Security 5.0开始,并且如果您正在使用Spring Boot或在配置中具有@EnableWebSecurity
注释,那么这种方法就可以工作
您可以在控制器的资源方法中使用HttpServletRequest
实例作为参数。使用此请求对象,您可以轻松获得csrf令牌
@Controller
@RequestMapping("/api/v1/test")
public class TestController {
@GetMapping
public String test(HttpServletRequest request) {
CsrfToken csrfToken =
(CsrfToken)httpServletRequest.getAttribute(CsrfToken.class.getName());
if(csrfToken != null)
return csrfToken.getToken();
return "Token Not Found";
}
}
用于使用java.util.UUID
类创建的Csrf令牌值,如下所示:-
UUID.randomUUID().toString();
检查org.springframework.security.web.csrf.CookieCsrfTokenRepository
和org.springframework.security.web.csrf.httpsessionsrftokenrepository
类,它们是CsrfTokenRepository
的实现,位于spring-security-web-X.X.X.RELEASE.jar
内部
如果您希望在cookie中使用CSRF令牌,并在客户端(如浏览器)响应,则:-
启用csrf并使用CookieSRFTokenRepository
csrf令牌存储库
从cookie名称为“XSRF-token”的cookie中获取令牌
在另一个请求[除GET、HEAD、TRACE、OPTIONS]标头中使用此令牌,标头键为X-XSRF-token
感谢您的回复@NikolaB。但它给出了空值。在调试中,我看到一个会话属性,其键为“org.springframework.security.web.csrf.httpsessionsrftokenrepository.csrf_TOKEN”。什么是“session”变量?如何获取对它的引用?您应该能够将它注入控制器(Spring将管理它):@Autowired private HttpSession;您基本上是从来自AJAX的服务器请求头中提取令牌。如果要获取headerName
、getParameterName
和token
,可以使用CsrfToken-token=new-httpsessionsrftokenrepository().loadToken(request).getHeaderName()获取
,CsrfToken-token=new-httpsessionsrftokenrepository().loadToken(请求).getParameterName()
和CsrfToken-token=new-httpsessionsrftokenrepository().loadToken(request.getToken()代码>分别为。
@Configuration
@EnableWebSecurity
public class ApplicationSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.and()
.....
.forLogin();
}
}