Java 如何在Spring中验证SockJS与JWT的连接

Java 如何在Spring中验证SockJS与JWT的连接,java,spring,spring-security,spring-websocket,sockjs,Java,Spring,Spring Security,Spring Websocket,Sockjs,我试图用SockJS连接到一个主题,但得到的响应是401。该项目包含带有JWT身份验证的Spring安全性。通过互联网搜索,我发现我应该在拦截器中对用户进行身份验证。问题是我的拦截器没有到达 在没有Spring安全性的POC(概念验证)应用程序中,一切正常 我希望我正确地描述了这个问题,提前谢谢 对用户进行身份验证的侦听器: @Component @RequiredArgsConstructor public class SocketAuthenticationInterceptor imple

我试图用SockJS连接到一个主题,但得到的响应是401。该项目包含带有JWT身份验证的Spring安全性。通过互联网搜索,我发现我应该在拦截器中对用户进行身份验证。问题是我的拦截器没有到达

在没有Spring安全性的POC(概念验证)应用程序中,一切正常

我希望我正确地描述了这个问题,提前谢谢

对用户进行身份验证的侦听器:

@Component
@RequiredArgsConstructor
public class SocketAuthenticationInterceptor implements ChannelInterceptor {
    private final JwtTokenProvider tokenProvider;
    private final UserDetailsServiceImpl userDetailsService;

    @Override
    public Message<?> preSend(Message<?> message, MessageChannel channel) {
                    StompHeaderAccessor accessor =
                            MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
                    if (StompCommand.CONNECT.equals(accessor.getCommand())) {
                        List<String> authorization = accessor.getNativeHeader("Authorization");
                        String jwt = authorization.get(0);
                        final Integer userId = tokenProvider.getUserIdFromJWT(jwt);

                        final UserDetails userDetails = userDetailsService.loadUserById(userId);
                        final UsernamePasswordAuthenticationToken authentication =
                                new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                        accessor.setUser(authentication);
                    }
                    return message;
    }
}

使用Springboot中的过滤器对用户的web请求进行身份验证。默认情况下,有一组筛选器尝试对任何请求进行身份验证。请注意,此身份验证是在握手期间和发送初始
CONNECT
消息之前完成的。
CustomInterceptor
用于处理我们收到的消息而不是用于身份验证,因为过滤器本身正在取消请求,甚至没有收到消息,因此执行不会到达拦截器。 因此,您可以像这样编写自己的自定义过滤器类

class JwtRequestFilter extends OncePerRequestFilter {
...
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException {
String requestTokenHeader = request.getHeader("Authorization");
if (requestTokenHeader != null && requestTokenHeader.startsWith("Bearer ")) {
                jwtToken = requestTokenHeader.substring(7);
 }
final Integer userId = tokenProvider.getUserIdFromJWT(jwtToken);
final UserDetails userDetails = userDetailsService.loadUserById(userId);
final UsernamePasswordAuthenticationToken authentication =new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
//If you want to set source details
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authentication);
   }
}
然后在
WebSecurityConfig.java

 @Override
 protected void configure(HttpSecurity httpSecurity) throws Exception {
  ...
   // Add a filter to validate the tokens with every request
        httpSecurity.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class); // Or any other filter of your choice
 }
这样就可以设置身份验证上下文。 有用链接:


  • 使用Springboot中的过滤器对用户的web请求进行身份验证。默认情况下,有一组筛选器尝试对任何请求进行身份验证。请注意,此身份验证是在握手期间和发送初始
    CONNECT
    消息之前完成的。
    CustomInterceptor
    用于处理我们收到的消息而不是用于身份验证,因为过滤器本身正在取消请求,甚至没有收到消息,因此执行不会到达拦截器。 因此,您可以像这样编写自己的自定义过滤器类

    class JwtRequestFilter extends OncePerRequestFilter {
    ...
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
                throws ServletException, IOException {
    String requestTokenHeader = request.getHeader("Authorization");
    if (requestTokenHeader != null && requestTokenHeader.startsWith("Bearer ")) {
                    jwtToken = requestTokenHeader.substring(7);
     }
    final Integer userId = tokenProvider.getUserIdFromJWT(jwtToken);
    final UserDetails userDetails = userDetailsService.loadUserById(userId);
    final UsernamePasswordAuthenticationToken authentication =new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
    //If you want to set source details
    authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
    SecurityContextHolder.getContext().setAuthentication(authentication);
       }
    }
    
    然后在
    WebSecurityConfig.java

     @Override
     protected void configure(HttpSecurity httpSecurity) throws Exception {
      ...
       // Add a filter to validate the tokens with every request
            httpSecurity.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class); // Or any other filter of your choice
     }
    
    这样就可以设置身份验证上下文。 有用链接:


  • 我也有同样的问题。你解决过这个问题吗?我也有同样的问题。你曾经解决过这个问题吗?