(SpringBoot v3.0,SpringSecurity v6.0)如何指定特定端点不安全/安全?

von4xj4u  于 2023-10-20  发布在  Spring
关注(0)|答案(2)|浏览(154)

我一直试图解决这个问题的日子,给了一个不同的错误,当我编译。所以我明白.antMatchers已经被弃用了,应该使用.requestMatchers。
但是,当我使用它时,它给出了“Spring安全方法无法决定模式是mvc还是不是spring Boot 应用程序异常”的错误。我在stackoverflow上看到了这篇文章,跟随修复但无济于事.
我设法得到它没有编译错误,但端点仍然是完全安全的,我无法指定我想不安全的端点。每次服务器启动时,我去的每个端点都会收到403。
这是我现在的代码:

@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {

    private final JwtAuthFilter jwtAuthFilter;
    private final AuthenticationProvider authenticationProvider;

    @Bean
    MvcRequestMatcher.Builder mvc(HandlerMappingIntrospector introspector) {
        return new MvcRequestMatcher.Builder(introspector)
                .servletPath("/api/v1");
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http, MvcRequestMatcher.Builder mvc) throws Exception {
        http
            .csrf(csrf -> csrf.disable())
            .authorizeHttpRequests((auth) -> auth
                .requestMatchers(mvc.pattern("/auth/**")).permitAll()
                .anyRequest().authenticated()
            )
            // stateless authentication 
            .sessionManagement(sess -> sess.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
            .authenticationProvider(authenticationProvider)
            .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);

        return http.build();
    }
}

编辑:JwtAuthFilter

@Component
@RequiredArgsConstructor
public class JwtAuthFilter extends OncePerRequestFilter {

    private final Middleware jwtService;

    private final UserDetailsService userDetailsService;

    @Override
    protected void doFilterInternal(@NonNull HttpServletRequest request, 
                                    @NonNull HttpServletResponse response, 
                                    @NonNull FilterChain filterChain)
            throws ServletException, IOException {

        try {
            final String authHeader = request.getHeader("Authorization");
            final String jwtToken;
            final String userEmail;

            if (authHeader == null || !authHeader.startsWith("Bearer ")) {
                filterChain.doFilter(request, response);
                return;
            }

            jwtToken = authHeader.substring(7);
            userEmail = jwtService.extractUsername(jwtToken);

            if (userEmail != null && SecurityContextHolder.getContext().getAuthentication() == null) {
                UserDetails userDetails = this.userDetailsService.loadUserByUsername(userEmail);

                if (jwtService.isTokenValid(jwtToken, userDetails)) {
                    UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(
                        userDetails, null, userDetails.getAuthorities()
                    );
                    authToken.setDetails(
                        new WebAuthenticationDetailsSource().buildDetails(request)
                    );
                    SecurityContextHolder.getContext().setAuthentication(authToken);
                }
            }

            filterChain.doFilter(request, response);

        } catch (Exception ex) {
            // Handle any exceptions here
        }

        // Continue the filter chain
        filterChain.doFilter(request, response);
    }

}
7z5jn7bk

7z5jn7bk1#

有关更多信息,如何避免此问题,我建议您检查README缓解措施部分,以及如何解释:

  • 在构造MvcRequestMatcher时分隔servlet路径对于确保请求正确匹配非常重要。*

Mitigations

更新

@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {

    private final JwtAuthFilter jwtAuthFilter;
    private final AuthenticationProvider authenticationProvider;

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http, HandlerMappingIntrospector introspector) throws Exception {
        MvcRequestMatcher.Builder mvcMatcherBuilder = new MvcRequestMatcher.Builder(introspector);
        http
            .csrf(AbstractHttpConfigurer::disable)
            .authorizeHttpRequests((auth) -> auth
                .requestMatchers(mvcMatcherBuilder.pattern("/api/v1/**")).permitAll()
                .requestMatchers(new AntPathRequestMatcher("/error/**")).permitAll()
                .anyRequest().authenticated()
            )
            // stateless authentication 
            .sessionManagement(sess -> sess.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
            .authenticationProvider(authenticationProvider)
            .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);

        System.out.println("Test");
        return http.build();
    }
}

也从application.properties中删除

server.servlet.context-path=/api/v1
v1uwarro

v1uwarro2#

我不认为你必须使用任何HandlerMappingIntrospector args和mvc之类的东西,
试试这个:

@Bean
       public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
            http
                    .csrf(AbstractHttpConfigurer::disable);
            http
                    .authorizeHttpRequests(
                            (request)->
                                    request
                    .requestMatchers("/api/v1/auth/**").permitAll().anyRequest().authenticated());
            http
                    .sessionManagement(
                            (session)->
                                    session
                                            .sessionCreationPolicy(SessionCreationPolicy.STATELESS));
            http
                    .authenticationProvider(authProvider);
    
        }
       }

Spring Security

相关问题