我使用的是Spring MVC/Security 3.X。问题是,每当会话超时时,我在登录页面上会得到403,Spring framework会抛出下面的“InvalidCsrfTokenException”:
threw exception [org.springframework.security.web.csrf.InvalidCsrfTokenException: Invalid CSRF Token '7b4aefe9-6685-4c70-adf1-0d633680523a' was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'.] with root cause
org.springframework.security.web.csrf.InvalidCsrfTokenException: Invalid CSRF Token '7b4aefe9-6685-4c70-adf1-0d633680523a' was found on the request parameter '_csrf' or header 'X-CSRF-TOKEN'.
at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:57)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:343)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:260)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.web.multipart.support.MultipartFilter.doFilterInternal(MultipartFilter.java:119)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1070)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:314)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
正如spring文档中提到的,CSRF超时是一个应该处理的问题。处理这种情况的一种方法是使用定制的AccessDeniedHandler,我们可以在其中拦截CSRF异常。比如:
static class CustomAccessDeniedHandler extends AccessDeniedHandlerImpl{
@Override
public void handle(HttpServletRequest request,
HttpServletResponse response,
AccessDeniedException accessDeniedException)
throws IOException, ServletException {
if (accessDeniedException instanceof MissingCsrfTokenException
|| accessDeniedException instanceof InvalidCsrfTokenException) {
//What goes in here???
}
super.handle(request, response, accessDeniedException);
}
}
问:处理这种情况的最佳方法是什么,而不必刷新页面(这是糟糕的用户体验)或进行无休止的会话?提前感谢您的帮助。
我使用construct:csrf()。禁用()。之后,错误消息将被消除,应用程序将正常工作(在Spring Boot 2.3、JSF 2.4、JDK 14下):
@Configuration
@EnableWebSecurity(debug = false)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.httpBasic().disable().csrf().disable();
}
}
使用Spring Security时,必须发送'_csrf'
,有以下几种方式:
形式:
在Ajax中:
$(function () {
var token = $("meta[name='_csrf']").attr("content");
var header = $("meta[name='_csrf_header']").attr("content");
$(document).ajaxSend(function(e, xhr, options) {
xhr.setRequestHeader(header, token);
});
});
来源:http://docs.spring.io/autorepo/docs/spring-security/3.2.0.CI-SNAPSHOT/reference/html/csrf.html
我发现,当登录页面的会话超时时,处理invalidate CSRF token的最简单方法是:
>
再次将请求重定向到登录页面vi CustomAccessDeniedHandler:
static class CustomAccessDeniedHandler extends AccessDeniedHandlerImpl{
@Override
public void handle(HttpServletRequest request,
HttpServletResponse response,
AccessDeniedException accessDeniedException)
throws IOException, ServletException {
if (accessDeniedException instanceof MissingCsrfTokenException
|| accessDeniedException instanceof InvalidCsrfTokenException) {
if(request.getRequestURI().contains("login")){
response.sendRedirect(request.getContextPath()+"/login");
}
}
super.handle(request, response, accessDeniedException);
}
}
按照Neil McGuigan的建议添加刷新标头:
在任何配置类中:
@Bean
public AccessDeniedHandler accessDeniedHandler() {
return new CustomAccessDeniedHandler();
}
在安全配置中,按如下方式修改配置方法:
@Override
protected void configure(final HttpSecurity http) throws Exception {
http
// ...
.and()
.exceptionHandling().accessDeniedHandler(accessDeniedHandler());
}
也请看这里。
Spring security将在其框架内处理这种情况,这将是一个更优化的解决方案。
我导入了这两个包(csrf、cookieparser),并在appjs中使用了express-js,它只工作,而且我在postman中测试了它的工作情况,这里是我的代码express-js: 还有我使用 react js 的前端,在 useEffect 中,我从后端获取 csrf,然后我保存在 axios 的标头中,但是当我向后端发送请求时,响应说无效的 csrf :/ 来自服务器的响应:Forb
概述 我将使用API网关作为基于Spring Security性的身份验证。我刚刚按照https://spring.io/guides/tutorials/spring-security-and-angular-js/链接中的步骤创建了一个基于其对应的github项目的“对双”模块的项目https://github.com/spring-guides/tut-spring-security-and
我正在使用Amazon SNS在我的HTTP/HTTPSendpoint上接收推送消息。endpoint应用程序是用Django编写的。要在endpoint(web app)上接收通知,HTTP/HTTPSendpoint需要订阅一个主题。 我的问题是当Amzaon SNS发送订阅确认时,它如何在POST请求中发送CSRF令牌,以便我处理请求并检索所需信息? 文档:http://docs.aws.
本页描述了解释CSRF攻击的用例(16.1): https://docs.spring.io/spring-security/site/docs/current/reference/html/csrf.html 但是,如果用户确实登录了银行的网站,那么邪恶的网站难道不可能发出GET请求以获取新的CSRF令牌,并在根本不需要用户的情况下撰写帖子吗? 答案必须是否定的,否则CSRF令牌将毫无用处,但我
问题内容: 和之间的实际区别是什么? 假设我希望用户会话在闲置15分钟后无效(而不是在第一次打开后15分钟内无效)。其中哪一项对我有帮助? 我也知道我可以这样做,可以将用户的Cookie设置为在一定时间内过期。但是,cookie过期与服务器端的实际会话过期是不相同的。Cookie过期后,这还会删除会话吗? 我的另一个解决方案是 对每个请求都很简单 ,然后将会话与当前时间进行比较,然后基于该时间删除
配置Spring Security 3.2后,csrf。令牌未绑定到请求或会话对象。 这是Spring Security配置: login.jsp文件 它呈现下一个html: 结果是403 HTTP状态: 在一些调试之后更新,请求对象以良好的形式发出DelegatingFilterProxy,但在CoyoteAdapter的469行中,它执行请求。回收();这会删除所有属性。。。 我使用JDK 1