如何使用Websocket和Spring安全性处理访问被拒绝的异常

时间:2017-01-11 05:12:06

标签: spring spring-security spring-websocket

我正在使用Spring安全性和Websocket,我有以下方法,

@PreAuthorize("hasAuthority('ROLE_CREATE_USER')")
@MessageMapping("/cashDeposit")
public void cashDeposit(CashDepositRequest cashDepositRequest) {

我有websocket安全配置。现在的问题是,当访问被拒绝时,它会抛出异常,

org.springframework.security.access.AccessDeniedException: Access is denied
at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:84) ~[spring-security-core-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:233) ~[spring-security-core-4.1.1.RELEASE.jar:4.1.1.RELEASE]

我搜索了Stackoverflow,发现大部分问题都与Servlets(HTTPServletRequest / Response)有关,而与Websocket无关。

请告诉我,如何处理websocket的AccessDeniedException以及如何将websocket消息发送回用户说403禁止。

更新

我的安全配置

@Configuration
public class WebSocketSecurityConfig extends          
AbstractSecurityWebSocketMessageBrokerConfigurer {

@Override
protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) {

    messages.simpMessageDestMatchers("/topic/**").permitAll()
            .anyMessage().authenticated();
}
@Override
protected boolean sameOriginDisabled() {
    //disable CSRF for websockets for now...
    return true;
}
}

我的休息服务安全配置,

    @Override
protected void configure(HttpSecurity http) throws Exception {
    http    .csrf().disable()
            .headers().addHeaderWriter( new XFrameOptionsHeaderWriter(
                    XFrameOptionsHeaderWriter.XFrameOptionsMode.SAMEORIGIN)).and()
            .authorizeRequests()
                .antMatchers("/index.html").permitAll()
                .antMatchers("/**.js").permitAll()
                .antMatchers("/**.css").permitAll()
                .anyRequest().authenticated().and()
            .authenticationProvider(authenticationProvider())
                .exceptionHandling()
                .authenticationEntryPoint(entryPoint)
                .and()
            .formLogin()
                .usernameParameter("username")
                .passwordParameter("password")
                .successHandler(loginSuccessHandler)
                .failureHandler(loginFailureHandler)
                .and()
            .logout()
                .permitAll()
                .logoutRequestMatcher(new AntPathRequestMatcher("/login", "DELETE"))
                .logoutSuccessHandler(logoutSuccessHandler)
                .deleteCookies("JSESSIONID")
                .invalidateHttpSession(true)
                .and()
            .sessionManagement()
                .enableSessionUrlRewriting(true)
                .maximumSessions(1);

}

1 个答案:

答案 0 :(得分:0)

您可以尝试这样的事情:

@MessageExceptionHandler
@SendToUser(destinations="/queue/errors", broadcast=false)
public ApplicationError handleException(AccessDeniedException exception) {
    // ...
    return appError;
}

来源:https://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html#websocket-stomp-user-destination