繁体   English   中英

MissingCsrfTokenException:无法验证提供的 CSRF 令牌,因为找不到您的 session

[英]MissingCsrfTokenException: Could not verify the provided CSRF token because your session was not found

我正在阅读 spring 文档: 将 CSRF 添加到 Stomp Header

我尝试将 stom header 添加到连接事件,但客户端出现错误:

>>> CONNECT
XSRF-TOKEN:f86232c1-e877-46e9-b4e6-7427c3d89940
accept-version:1.1,1.0
heart-beat:10000,10000

<<< ERROR
message:Failed to send message to ExecutorSubscribableChannel[clientInboundChannel]; nested exception is org.springframework.security.web.csrf.MissingCsrfTokenException\c Could not verify the provided CSRF token because your session was not found.
content-length:0

客户端代码:

<script type="text/javascript" src="/webjars/js-cookie/js.cookie.js"></script>

var headers = {};
    var headerName = "XSRF-TOKEN";
    var token = Cookies.get('XSRF-TOKEN')
    headers[headerName] = token;
    stompClient.connect(headers, function (frame) {....});

websocket 安全配置:

@Configuration
    public class WebSocketAuthorizationSecurityConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer {
        @Override
        protected void configureInbound(final MessageSecurityMetadataSourceRegistry messages) {
            // You can customize your authorization mapping here.
            messages.anyMessage().authenticated();
            messages.simpDestMatchers("/app/hello").authenticated()//.hasRole("ADMIN")
                    .simpSubscribeDestMatchers("/user/queue/**").hasRole("ADMIN")
                    .simpSubscribeDestMatchers("/topic/greetings").authenticated();
        }

        // TODO: For test purpose (and simplicity) i disabled CSRF, but you should re-enable this and provide a CRSF endpoint.
        @Override
        protected boolean sameOriginDisabled() {
            return false; //! I do it especially
        }
    }

spring 安全配置:

@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    private static final String SECURE_ADMIN_PASSWORD = "rockandroll";

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                .formLogin()
                .loginPage("/index.html")
                    .loginProcessingUrl("/login")
                    .defaultSuccessUrl("/sender.html")
                    .permitAll()
                .and()
                .logout()
                    .logoutSuccessUrl("/index.html")
                    .permitAll()
                .and()
                .authorizeRequests()
                .antMatchers("/js/**", "/lib/**", "/images/**", "/css/**", "/index.html", "/","/*.css","/webjars/**", "/*.js").permitAll()
                .antMatchers("/websocket").hasRole("ADMIN")
                .requestMatchers(EndpointRequest.toAnyEndpoint()).hasRole("ADMIN")
                .anyRequest().authenticated();

    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {

        auth.authenticationProvider(new AuthenticationProvider() {

            @Override
            public boolean supports(Class<?> authentication) {
                return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
            }

            @Override
            public Authentication authenticate(Authentication authentication) throws AuthenticationException {
                UsernamePasswordAuthenticationToken token = (UsernamePasswordAuthenticationToken) authentication;

                List<GrantedAuthority> authorities = SECURE_ADMIN_PASSWORD.equals(token.getCredentials()) ?
                        AuthorityUtils.createAuthorityList("ROLE_ADMIN") : null;

                return new UsernamePasswordAuthenticationToken(token.getName(), token.getCredentials(), authorities);
            }
        });
    }
}

也许我的 csrf token header 名字错了?

聚苯乙烯

服务器端消息

这个问题不在 Spring 框架中。 更新到 Spring-Boot(2.5.0,war+Tomcat 9 实现,OAuth2)后,我遇到了同样的问题。

这个对我有用:

  1. 第 1 步(为 Websockets 添加安全配置 - 您需要禁用 SCRF Websocket 保护)

    导入 org.springframework.context.annotation.Configuration; 导入 org.springframework.messaging.simp.SimpMessageType; 导入 org.springframework.security.config.annotation.web.messaging.MessageSecurityMetadataSourceRegistry; 导入 org.springframework.security.config.annotation.web.socket.AbstractSecurityWebSocketMessageBrokerConfigurer;

    @Configuration public class SocketSecurityConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer {

     @Override protected boolean sameOriginDisabled() { return true; } @Override protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) { messages.simpTypeMatchers(SimpMessageType.CONNECT, SimpMessageType.HEARTBEAT, SimpMessageType.UNSUBSCRIBE, SimpMessageType.DISCONNECT).permitAll().anyMessage().permitAll().simpDestMatchers("/**").permitAll(); }

    }

  2. 第2步(在Web Security配置中添加Access to Websockets and Stomp):

    导入 lombok.RequiredArgsConstructor; 导入 lombok.extern.slf4j.Slf4j; 导入 org.springframework.beans.factory.annotation.Autowired; 导入 org.springframework.context.annotation.ComponentScan; 导入 org.springframework.context.annotation.Configuration; 导入 org.springframework.security.config.annotation.web.builders.HttpSecurity; 导入 org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 导入 org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 导入 org.springframework.security.config.http.SessionCreationPolicy;

    @Slf4j @EnableWebSecurity @ComponentScan("com.example.your.project.package.name") @Configuration @RequiredArgsConstructor(onConstructor = @__(@Autowired)) public class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {

     private static final String[] OPEN_URIS = { "/**/*.woff", "/**/*.woff2", "/**/*.ttf", "/webjars/**", "/login", "/login/*", "/login/*/**", "/resources/**", "/error", "/error/*", "/error/*/**", "/oauth2/authorization/**", "/**/*.png", "/**/*.css", "/**/*.js", "/style.css", "/favicon.ico", "/wicket", "/wicket/resource/", "/wicket/resource/*", "/wicket/resource/*/**", "/wicket/resources/**", "/wicket/resources/*/**", "/wicket/*", "/wicket/page/*", "/wicket/page/*/**", "/webjars", "/webjars/*", "/webjars/*/**", "/webservices/websocket/", "/webservices/websocket/*", "/webservices/websocket/*/**", "/webservices/websocketHandlerEndpoint", "/webservices/websocketHandlerEndpoint/*", "/webservices/websocketHandlerEndpoint/*/**" }; /////---Here some Configuration (not showed)------------ ///// @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable().headers().frameOptions().sameOrigin().httpStrictTransportSecurity().disable().and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.ALWAYS).and().authorizeRequests(authorize -> authorize.antMatchers(OPEN_URIS).permitAll()) // (Optional: ).oauth2Login(oauth2 -> oauth2.permitAll() // <-- actually not real, but here must be code //....`enter code here`.. // ) //..... .logout() //... ; } //another part of Configuration.....

    }

注意: 1)"/webservices/websocket/..." - 是 Stomp 端点 2) "/webservices/websocketHandlerEndpoint..." - 是 Websocket 处理程序端点

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM