java Spring Security:返回403 Forbidden for all requests after successful authentication

rvpgvaaj  于 2023-05-12  发布在  Java
关注(0)|答案(1)|浏览(139)

我希望允许所有用户通过JWT登录。仅允许登录的用户访问专用端点。没有记录任何内容,甚至没有“拒绝访问”。下面是我的SecurityConfig配置类。

@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
@EnableMethodSecurity
public class SecurityConfig {

    private final JwtAuthenticationFilter jwtAuthFilter;
    private final AuthenticationProvider authProvider;

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeHttpRequests()
                .requestMatchers(publicEndpoints()).permitAll()
                .requestMatchers(userEndpoints()).permitAll()
                .requestMatchers(adminEndpoints()).hasRole("ADMIN")
                .anyRequest().denyAll()
                .and()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authenticationProvider(authProvider)
                .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class)
                .exceptionHandling()
                .accessDeniedHandler((request, response, ex) -> {
                    System.out.println("Access Denied: " + ex.getMessage());
                    response.sendError(HttpServletResponse.SC_FORBIDDEN);
                });

        return http.build();
    }

    private RequestMatcher userEndpoints() {
        return new OrRequestMatcher(
                new AntPathRequestMatcher("/u/**")
        );
    }

    private RequestMatcher adminEndpoints() {
        return new OrRequestMatcher(
                new AntPathRequestMatcher("/admin/**")
        );
    }

    private RequestMatcher publicEndpoints() {
        return new OrRequestMatcher(
                new AntPathRequestMatcher("/user/register"),
                new AntPathRequestMatcher("/user/signin")
        );
    }
}

下面是JwtAuthenticationFilter:

@Component
@RequiredArgsConstructor
public class JwtAuthenticationFilter extends OncePerRequestFilter {

    private final JwtService jwtService;
    private final UserDetailsService userDetailsService;

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

        final String authHeader = request.getHeader("Authorization");

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

        final String jwtToken = authHeader.substring(7); // removes "Bearer " string.
        final String username = jwtService.extractUsername(jwtToken);

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

            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);
    }
}

目前,使用上述配置,我没有得到任何日志。我尝试将安全配置更改为.requestMatchers(userEndpoints()).hasRole("USER"),但仍然返回403 Forbidden。但这一次,有一个日志说“访问被拒绝:拒绝访问”。
我也尝试过使用@PreAuthorize("hasRole('USER')")作为被调用的控制器方法,但也没有什么效果。

a0zr77ik

a0zr77ik1#

SecurityConfig类中,在securityFilterChain方法中,使用的是**“denyAll()"方法。有了它,你说所有上述要求都应该被拒绝。将denyAll()修改为authenticated()**。
方法如下:

@Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeHttpRequests()
                .requestMatchers(publicEndpoints()).permitAll()
                .requestMatchers(userEndpoints()).permitAll()
                .requestMatchers(adminEndpoints()).hasRole("ADMIN")
                .anyRequest().authenticated()
                .and()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authenticationProvider(authProvider)
                .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class)
                .exceptionHandling()
                .accessDeniedHandler((request, response, ex) -> {
                    System.out.println("Access Denied: " + ex.getMessage());
                    response.sendError(HttpServletResponse.SC_FORBIDDEN);
                });

        return http.build();
    }

相关问题