Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 获取弹簧控制器中的csrf_Java_Spring_Spring Mvc_Spring Security_Csrf - Fatal编程技术网

Java 获取弹簧控制器中的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

如何在spring控制器中获取_csrf对象(?)?我已经配置了Spring安全性,可以在jsp文件中获取${u csrf}请求属性。 我试过:

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();
       }
    }