【发布时间】:2018-10-08 10:42:42
【问题描述】:
我正在阅读 spring 文档:Adding CSRF to Stomp Header
我尝试将 stom 标头添加到连接事件,但我在客户端收到错误:
>>> 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
}
}
弹簧安全配置:
@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 令牌标头名称错误?
附言
【问题讨论】:
-
您是否将 CSRF Cookie 与您的请求一起发送?如果我不发送 cookie,我会收到该错误。它必须具有正确的域才能让您的浏览器发送它。
-
@Will M,我该如何检查?
-
这取决于您使用什么来发送请求。如果它来自浏览器,通过网站,那么您应该使用该浏览器的开发人员工具。如果你是通过邮递员或其他工具制作的,它应该有一种内置的方式来查看你的 cookie 是什么
-
我无法编辑这篇文章,因为它主要是代码,不会让我编辑,如果其他人可以,请用这个完整的链接替换 Adding CSRF to Stomp Header。
标签: java spring-security websocket csrf spring-websocket