如何在Spring中通过JWT验证SockJS CONNECT

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

我正在尝试使用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;
    }
}

注册拦截器:

@Configuration
@RequiredArgsConstructor
@EnableWebSocketMessageBroker
@Order(Ordered.HIGHEST_PRECEDENCE + 99)
public class WebSocketAuthenticationConfig implements WebSocketMessageBrokerConfigurer {

    private final SocketAuthenticationInterceptor socketAuthenticationInterceptor;

    @Override
    public void configureClientInboundChannel(final ChannelRegistration registration) {
        registration.interceptors(socketAuthenticationInterceptor);
    }
}
java spring spring-security spring-websocket sockjs
1个回答
0
投票
在Springboot中使用

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

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 }

因此,您的身份验证上下文已设置。有用的链接:

  1. Spring Security Architecture

  2. Adding Custom Filter in SpringBoot
  3. More on Web Security in Spring
  4. Bearer schema JWT Token
© www.soinside.com 2019 - 2024. All rights reserved.