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

时间:2018-04-27 14:45:20

标签: java spring-security websocket csrf spring-websocket

我正在阅读春季文档:Adding CSRF to Stomp Header

我尝试将stom标头添加到connect事件中,但我在客户端上收到错误:

>>> 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 security config:

@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令牌头名称错了?

P.S。

server side message

0 个答案:

没有答案