无法向 ExecutorSubscribableChannel[clientInboundChannel] 发送消息

问题描述 投票:0回答:2

我使用 Spring Boot、Spring Security、Spring websockets、stomp 和 sockjs 开发了一个移动聊天应用程序。服务器运行在 8082 端口,客户端运行在 8100 端口。

我正在使用 Angular 和 sockjs 客户端发送请求。当我尝试连接到 STOMP 端点时,它在开发人员控制台(前端)和后端控制台处给出错误。下面是轨迹,

浏览器控制台

Opening Web Socket...
stomp.min.js (line 8)
GET http://localhost:8082/ws/info?t=1451547968350

200 OK
565ms

sockjs-1.0.1.js (line 1610)
Web Socket Opened...
stomp.min.js (line 8)

CONNECT
login:test
passcode:test
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.access.AccessDeniedException\c Access is denied
content-length:0*

服务器日志

2015-12-31 13:16:09.080 DEBUG 8116 --- [0.0-8082-exec-1] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/ws/info'; against '/css/'
2015-12-31 13:16:09.081 DEBUG 8116 --- [0.0-8082-exec-1] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/ws/info'; against '/js/'
2015-12-31 13:16:09.081 DEBUG 8116 --- [0.0-8082-exec-1] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/ws/info'; against '/images/'
2015-12-31 13:16:09.081 DEBUG 8116 --- [0.0-8082-exec-1] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/ws/info'; against '//favicon.ico'
2015-12-31 13:16:09.081 DEBUG 8116 --- [0.0-8082-exec-1] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/ws/info'; against '/error'
2015-12-31 13:16:09.081 DEBUG 8116 --- [0.0-8082-exec-1] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'GET /ws/info' doesn't match 'POST /person/**
2015-12-31 13:16:09.081 DEBUG 8116 --- [0.0-8082-exec-1] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/ws/info'; against '/lookup/'
2015-12-31 13:16:09.081 DEBUG 8116 --- [0.0-8082-exec-1] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'GET /ws/info' doesn't match 'POST /upload/image/
2015-12-31 13:16:09.081 DEBUG 8116 --- [0.0-8082-exec-1] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/ws/info'; against '/ws/'
2015-12-31 13:16:09.082 DEBUG 8116 --- [0.0-8082-exec-1] o.s.security.web.FilterChainProxy : /ws/info?t=1451547968350 has an empty filter list
2015-12-31 13:16:09.093 DEBUG 8116 --- [0.0-8082-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'managementServerProperties'
2015-12-31 13:16:09.110 DEBUG 8116 --- [0.0-8082-exec-1] o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/ws/info]
2015-12-31 13:16:09.120 DEBUG 8116 --- [0.0-8082-exec-1] o.s.b.a.e.mvc.EndpointHandlerMapping : Looking up handler method for path /ws/info
2015-12-31 13:16:09.160 DEBUG 8116 --- [0.0-8082-exec-1] o.s.b.a.e.mvc.EndpointHandlerMapping : Did not find handler method for [/ws/info]
2015-12-31 13:16:09.161 DEBUG 8116 --- [0.0-8082-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /ws/info
2015-12-31 13:16:09.164 DEBUG 8116 --- [0.0-8082-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Did not find handler method for [/ws/info]
2015-12-31 13:16:09.165 DEBUG 8116 --- [0.0-8082-exec-1] o.s.w.s.s.s.WebSocketHandlerMapping : Matching patterns for request [/ws/info] are [/ws/]
2015-12-31 13:16:09.168 DEBUG 8116 --- [0.0-8082-exec-1] o.s.w.s.s.s.WebSocketHandlerMapping : URI Template variables for request [/ws/info] are {}
2015-12-31 13:16:09.171 DEBUG 8116 --- [0.0-8082-exec-1] o.s.w.s.s.s.WebSocketHandlerMapping : Mapping [/ws/info] to HandlerExecutionChain with handler [org.springframework.web.socket.sockjs.support.SockJsHttpRequestHandler@3e16086] and 1 interceptor
2015-12-31 13:16:09.177 DEBUG 8116 --- [0.0-8082-exec-1] o.s.web.servlet.DispatcherServlet : Last-Modified value for [/ws/info] is: -1
2015-12-31 13:16:09.280 DEBUG 8116 --- [0.0-8082-exec-1] o.s.w.s.s.t.h.DefaultSockJsService : Processing transport request: GET http://localhost:8082/ws/info?t=1451547968350
2015-12-31 13:16:09.292 DEBUG 8116 --- [0.0-8082-exec-1] o.s.web.servlet.DispatcherServlet : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
2015-12-31 13:16:09.292 DEBUG 8116 --- [0.0-8082-exec-1] o.s.web.servlet.DispatcherServlet : Successfully completed request
2015-12-31 13:16:09.298 DEBUG 8116 --- [0.0-8082-exec-1] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'delegatingApplicationListener'
2015-12-31 13:16:09.657 DEBUG 8116 --- [0.0-8082-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/ws/849/3qaa31j0/websocket'; against '/css/'
2015-12-31 13:16:09.657 DEBUG 8116 --- [0.0-8082-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/ws/849/3qaa31j0/websocket'; against '/js/'
2015-12-31 13:16:09.657 DEBUG 8116 --- [0.0-8082-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/ws/849/3qaa31j0/websocket'; against '/images/'
2015-12-31 13:16:09.657 DEBUG 8116 --- [0.0-8082-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/ws/849/3qaa31j0/websocket'; against '//favicon.ico'
2015-12-31 13:16:09.657 DEBUG 8116 --- [0.0-8082-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/ws/849/3qaa31j0/websocket'; against '/error'
2015-12-31 13:16:09.657 DEBUG 8116 --- [0.0-8082-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'GET /ws/849/3qaa31j0/websocket' doesn't match 'POST /person/**
2015-12-31 13:16:09.657 DEBUG 8116 --- [0.0-8082-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/ws/849/3qaa31j0/websocket'; against '/lookup/'
2015-12-31 13:16:09.657 DEBUG 8116 --- [0.0-8082-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'GET /ws/849/3qaa31j0/websocket' doesn't match 'POST /upload/image/
2015-12-31 13:16:09.657 DEBUG 8116 --- [0.0-8082-exec-2] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/ws/849/3qaa31j0/websocket'; against '/ws/'
2015-12-31 13:16:09.658 DEBUG 8116 --- [0.0-8082-exec-2] o.s.security.web.FilterChainProxy : /ws/849/3qaa31j0/websocket has an empty filter list
2015-12-31 13:16:09.659 DEBUG 8116 --- [0.0-8082-exec-2] o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/ws/849/3qaa31j0/websocket]
2015-12-31 13:16:09.659 DEBUG 8116 --- [0.0-8082-exec-2] o.s.b.a.e.mvc.EndpointHandlerMapping : Looking up handler method for path /ws/849/3qaa31j0/websocket
2015-12-31 13:16:09.688 DEBUG 8116 --- [0.0-8082-exec-2] o.s.b.a.e.mvc.EndpointHandlerMapping : Did not find handler method for [/ws/849/3qaa31j0/websocket]
2015-12-31 13:16:09.688 DEBUG 8116 --- [0.0-8082-exec-2] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /ws/849/3qaa31j0/websocket
2015-12-31 13:16:09.690 DEBUG 8116 --- [0.0-8082-exec-2] s.w.s.m.m.a.RequestMappingHandlerMapping : Did not find handler method for [/ws/849/3qaa31j0/websocket]
2015-12-31 13:16:09.690 DEBUG 8116 --- [0.0-8082-exec-2] o.s.w.s.s.s.WebSocketHandlerMapping : Matching patterns for request [/ws/849/3qaa31j0/websocket] are [/ws/]
2015-12-31 13:16:09.690 DEBUG 8116 --- [0.0-8082-exec-2] o.s.w.s.s.s.WebSocketHandlerMapping : URI Template variables for request [/ws/849/3qaa31j0/websocket] are {}
2015-12-31 13:16:09.690 DEBUG 8116 --- [0.0-8082-exec-2] o.s.w.s.s.s.WebSocketHandlerMapping : Mapping [/ws/849/3qaa31j0/websocket] to HandlerExecutionChain with handler [org.springframework.web.socket.sockjs.support.SockJsHttpRequestHandler@3e16086] and 1 interceptor
2015-12-31 13:16:09.690 DEBUG 8116 --- [0.0-8082-exec-2] o.s.web.servlet.DispatcherServlet : Last-Modified value for [/ws/849/3qaa31j0/websocket] is: -1
2015-12-31 13:16:09.692 DEBUG 8116 --- [0.0-8082-exec-2] o.s.w.s.s.t.h.DefaultSockJsService : Processing transport request: GET http://localhost:8082/ws/849/3qaa31j0/websocket
2015-12-31 13:16:09.812 DEBUG 8116 --- [0.0-8082-exec-2] o.s.web.servlet.DispatcherServlet : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
2015-12-31 13:16:09.813 DEBUG 8116 --- [0.0-8082-exec-2] o.s.web.servlet.DispatcherServlet : Successfully completed request
2015-12-31 13:16:09.882 DEBUG 8116 --- [0.0-8082-exec-2] s.w.s.h.LoggingWebSocketHandlerDecorator : New WebSocketServerSockJsSession[id=3qaa31j0]
2015-12-31 13:16:10.091 DEBUG 8116 --- [0.0-8082-exec-3] o.s.s.m.a.i.ChannelSecurityInterceptor : Secure object: GenericMessage [payload=byte[0], headers={simpMessageType=CONNECT, stompCommand=CONNECT, nativeHeaders={login=[test], passcode=[PROTECTED], accept-version=[1.1,1.0], heart-beat=[10000,10000]}, simpSessionAttributes=**{IP_ADDRESS=/127.0.0.1:51223, Access-Control-Allow-Origin=*}, simpHeartbeat=[J@574f3f7, stompCredentials=[PROTECTED], simpUser=org.springframework.security.authentication.AnonymousAuthenticationToken@55c70fe4: Principal: anonymous; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ANONYMOUS, simpSessionId=3qaa31j0}]; Attributes: [authenticated]
2015-12-31 13:16:10.091 DEBUG 8116 --- [0.0-8082-exec-3] o.s.s.m.a.i.ChannelSecurityInterceptor : Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@55c70fe: Principal: anonymous; Credentials: [PROTECTED]; Authenticated: true; Details: null; Granted Authorities: ANONYMOUS
2015-12-31 13:16:10.104 DEBUG 8116 --- [0.0-8082-exec-3] o.s.s.access.vote.AffirmativeBased : Voter: org.springframework.security.messaging.access.expression.MessageExpressionVoter@6f9f78f, returned: -1**
2015-12-31 13:16:10.119 DEBUG 8116 --- [0.0-8082-exec-3] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'delegatingApplicationListener'
2015-12-31 13:16:10.120 DEBUG 8116 --- [0.0-8082-exec-3] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'authorizationAuditListener'
2015-12-31 13:16:10.121 DEBUG 8116 --- [0.0-8082-exec-3] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'delegatingApplicationListener'
2015-12-31 13:16:10.122 DEBUG 8116 --- [0.0-8082-exec-3] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'auditListener'
2015-12-31 13:16:10.122 DEBUG 8116 --- [0.0-8082-exec-3] o.s.b.a.audit.listener.AuditListener : AuditEvent [timestamp=Thu Dec 31 13:16:10 IST 2015, principal=anonymous, type=AUTHORIZATION_FAILURE, data={type=org.springframework.security.access.AccessDeniedException, message=Access is denied}]
2015-12-31 13:16:10.125 ERROR 8116 --- [0.0-8082-exec-3] o.s.w.s.m.StompSubProtocolHandler : Failed to send client message to application via MessageChannel in session 3qaa31j0. Sending STOMP ERROR to client.

org.springframework.messaging.MessageDeliveryException: Failed to send message to ExecutorSubscribableChannel[clientInboundChannel]; nested exception is org.springframework.security.access.AccessDeniedException: Access is denied
at org.springframework.messaging.support.AbstractMessageChannel.send(AbstractMessageChannel.java:127) ~[spring-messaging-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.messaging.support.AbstractMessageChannel.send(AbstractMessageChannel.java:104) ~[spring-messaging-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.web.socket.messaging.StompSubProtocolHandler.handleMessageFromClient(StompSubProtocolHandler.java:280) ~[spring-websocket-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.web.socket.messaging.SubProtocolWebSocketHandler.handleMessage(SubProtocolWebSocketHandler.java:317) [spring-websocket-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.web.socket.handler.WebSocketHandlerDecorator.handleMessage(WebSocketHandlerDecorator.java:75) [spring-websocket-4.2.3.RELEASE.jar:4.2.3.RELEASE

Angular 和 sockjs 代码文件

chatController.js

angular.module('letsCatchApp').controller(
'chatController',
function($scope, $location, $interval, toaster, chatSocket,$state) {
      var typing = undefined;
      $scope.username     = '';
        $scope.sendTo       = 'everyone';
        $scope.participants = [];
        $scope.messages     = [];
        $scope.newMessage   = ''; 

        $scope.sendMessage = function() {
            console.log('22222');
            var destination = "http://localhost:8082/app/chat.message";

            if($scope.sendTo != "everyone") {
                destination = "http://localhost:8082/app/chat.private." + $scope.sendTo;
                $scope.messages.unshift({message: $scope.newMessage, username: 'you', priv: true, to: $scope.sendTo});
            }

            chatSocket.send(destination, {}, JSON.stringify({message: $scope.newMessage}));
            $scope.newMessage = '';
        };

        $scope.startTyping = function() {
          // Don't send notification if we are still typing or we are typing a private message
            if (angular.isDefined(typing) || $scope.sendTo != "everyone") return;

            typing = $interval(function() {
                    $scope.stopTyping();
                }, 500);

            chatSocket.send("http://localhost:8082/topic/chat.typing", {}, JSON.stringify({username: $scope.username, typing: true}));
        };

        $scope.stopTyping = function() {
            console.log('44444');
            if (angular.isDefined(typing)) {
                $interval.cancel(typing);
                typing = undefined;

                chatSocket.send("http://localhost:8082/topic/chat.typing", {}, JSON.stringify({username: $scope.username, typing: false}));
            }
        };

        $scope.privateSending = function(username) {
            console.log('55555');
                $scope.sendTo = (username != $scope.sendTo) ? username : 'everyone';
        };

        $scope.initStompClient = function() {
            console.log('66666');
            chatSocket.init('http://localhost:8082/ws');
            console.log('66666rrrrrrrrrrrrrrrrr');
            chatSocket.connect(function(frame) {

                console.log('101010101010101');
                $scope.username = frame.headers['user-name'];

                chatSocket.subscribe("http://localhost:8082/app/chat.participants", function(message) {
                    console.log('7777');
                    $scope.participants = JSON.parse(message.body);
                });

                chatSocket.subscribe("http://localhost:8082/topic/chat.login", function(message) {
                    console.log('888888');
                    $scope.participants.unshift({username: JSON.parse(message.body).username, typing : false});
                });

                chatSocket.subscribe("http://localhost:8082/topic/chat.logout", function(message) {
                    console.log('99999');
                    var username = JSON.parse(message.body).username;
                    for(var index in $scope.participants) {
                        if($scope.participants[index].username == username) {
                            $scope.participants.splice(index, 1);
                        }
                    }
                });

                chatSocket.subscribe("http://localhost:8082/topic/chat.typing", function(message) {
                    var parsed = JSON.parse(message.body);
                    if(parsed.username == $scope.username) return;

                    for(var index in $scope.participants) {
                        var participant = $scope.participants[index];

                        if(participant.username == parsed.username) {
                            $scope.participants[index].typing = parsed.typing;
                        }
                    } 
                });

                chatSocket.subscribe("http://localhost:8082/topic/chat.message", function(message) {
                    console.log('88888');
                    $scope.messages.unshift(JSON.parse(message.body));
                });

                chatSocket.subscribe("http://localhost:8082/user/exchange/amq.direct/chat.message", function(message) {
                    console.log('9999');
                    var parsed = JSON.parse(message.body);
                    parsed.priv = true;
                    $scope.messages.unshift(parsed);
                });

                chatSocket.subscribe("http://localhost:8082/user/exchange/amq.direct/errors", function(message) {
                    toaster.pop('error', "Error", message.body);
                });

            }, function(error) {
                console.log("errrooooooo=======   "+error);
                toaster.pop('error', 'Error', 'Connection error ' + error);

            });
        };

        //initStompClient();
    });

chatService.js

angular.module('letsCatchApp').service('chatSocket',
function($rootScope,$http) {

        console.log('Chat service is called.... ');


    var stompClient;

     this.test = function() {
         console.log('Chat service test... ');
         return $http.get('http://localhost:8082/app/')
      }

 this.init = function(url) {
       console.log('Chat service init ... '+url);
        stompClient = Stomp.over(new SockJS(url));
        console.log('Chat service init ...end---- '+url);
  }

 this.connect = function(successCallback, errorCallback) {
     console.log('Chat service init ... connect');

        stompClient.connect({'login': 'test',
            'passcode': 'test'}, function(frame) {
           $rootScope.$apply(function() {
                return successCallback(frame);
            });
            }, function(error) {
                $rootScope.$apply(function(){
                    return errorCallback(error);
            });
        });
    }

   this.subscribe = function(destination, callback) {
       console.log('Chat service init ... subscribe');
        stompClient.subscribe(destination, function(message) {
                $rootScope.$apply(function(){
                    return callback(message);
            });
      });   
    }

  this.send = function(destination, headers, object) {
        return stompClient.send(destination, headers, object);
    }

});

Java 配置

WebSocketConfig.java

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    public static final String IP_ADDRESS = "IP_ADDRESS";

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        egistry.addEndpoint("/ws").setAllowedOrigins("*").withSockJS();

        registry.addEndpoint("/ws").setAllowedOrigins("*").setHandshakeHandler(new DefaultHandshakeHandler() {
            @Override
            protected Principal determineUser(ServerHttpRequest request, WebSocketHandler wsHandler, Map<String, Object> attributes) {
                Principal principal = request.getPrincipal();
                if (principal == null) {
                    Collection<SimpleGrantedAuthority> authorities = new ArrayList<>();
                    authorities.add(new SimpleGrantedAuthority("ANONYMOUS"));
                    principal = new AnonymousAuthenticationToken("WebsocketConfiguration", "anonymous", authorities);
                }
                return principal;
            }
        }).withSockJS().setInterceptors(httpSessionHandshakeInterceptor());
    }

    @Bean
    public HandshakeInterceptor httpSessionHandshakeInterceptor() {
        return new HandshakeInterceptor() {

            @Override
            public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
                if (request instanceof ServletServerHttpRequest) {
                    ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
                    attributes.put(IP_ADDRESS, servletRequest.getRemoteAddress());
                    attributes.put("Access-Control-Allow-Origin", "*");
                }
                return true;
            }

            @Override
            public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) {

            }
        };
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        System.out.println("registering the endpoint ==of ===/queue/===========");
        registry.enableSimpleBroker("/queue/", "/topic/", "/exchange/");
        // registry.enableStompBrokerRelay("/queue/", "/topic/", "/exchange/");
        registry.setApplicationDestinationPrefixes("/app");
    }

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> arg0) {}
    @Override
    public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> arg0) {}
    @Override
    public void configureClientInboundChannel(ChannelRegistration arg0) {}
    @Override
    public void configureClientOutboundChannel(ChannelRegistration arg0) {}
    @Override
    public boolean configureMessageConverters(List<MessageConverter> arg0) { return false; }
    @Override
    public void configureWebSocketTransport(WebSocketTransportRegistration arg0) {}
}

WebsecurityConfig.java

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

    @Autowired
    private CustomUserDetailsService customUserDetailsService;

    @Autowired
    private RoleService roleService;

    /**
     * This section defines the user accounts which can be used for
     * authentication as well as the roles each user has.
     */
    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(customUserDetailsService);
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers(HttpMethod.POST, "/person/**")
                //.antMatchers(HttpMethod.OPTIONS, "/**")
                .antMatchers(HttpMethod.GET, "/lookup/**")
                .antMatchers(HttpMethod.POST, "/upload/image/**")
                .antMatchers(HttpMethod.GET, "/ws/**")
                .antMatchers(HttpMethod.GET, "/topic/**")
                .antMatchers(HttpMethod.GET, "/app/**");

    }

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        Iterable<com.sergialmar.wschat.model.Role> roleIterable = roleService.getRoles();
        List<Role> roleList = new ArrayList<Role>();

        Iterator<Role> iterator = roleIterable.iterator();
        while (iterator.hasNext()) {
            Role role = iterator.next();
            roleList.add(role);
            System.out.println("Roles : " + role.getName());
        }

        String[] roles = new String[roleList.size()];

        for (int roleIndex = 0; roleIndex < roleList.size(); roleIndex++) {
            roles[roleIndex] = roleList.get(roleIndex).getName();
        }

        http.httpBasic().and().authorizeRequests()
                .antMatchers(HttpMethod.GET, "/**").hasAnyAuthority(roles)
                .antMatchers(HttpMethod.POST, "/**").hasAnyAuthority(roles)
                .antMatchers(HttpMethod.PUT, "/**").hasAnyAuthority(roles)
                .antMatchers(HttpMethod.DELETE, "/**").hasAnyAuthority(roles)
                .antMatchers(HttpMethod.OPTIONS, "/**").hasAnyAuthority(roles)

                .and().csrf().disable();
        http.headers().frameOptions().disable();
    }
}
spring-security websocket spring-boot stomp sockjs
2个回答
0
投票

JS 是否在 header 中添加 auth token ?

var headers = {};
    var csrf = self.csrfToken();
    headers[csrf.headerName] = csrf.token;
    headers['X-AUTH-TOKEN'] = AUTH_TOKEN;
    stompClient.connect(headers, function(frame) );

暂时禁用与安全相关的配置,例如: 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().authenticated() //or permitAll
                .simpDestMatchers("/**").authenticated();//or permitAll

}

WebSecurityConfigurerAdapter:
    http.csrf().disable();
    http.headers().frameOptions().disable()
                 .httpStrictTransportSecurity().disable();

0
投票

setAllowedOrigins("*")
对我不起作用。
您可能需要明确添加您的来源。 (例如。
["http://localhost:3000"]

此外,您还可以通过调试拦截器来获取更多信息。

org.springframework.security.messaging.web.socket: DEBUG
org.springframework.web.socket.server: DEBUG
© www.soinside.com 2019 - 2024. All rights reserved.