java - 公共(public)端点上的 Spring Boot REST API 401?

标签 java spring rest spring-boot spring-security

我在负责注册的不安全端点上收到401 Unauthorized:

这是我使用的 Config 类:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
//@FieldDefaults(level = PRIVATE, makeFinal = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    private static final RequestMatcher PUBLIC_URLS = new OrRequestMatcher(
            new AntPathRequestMatcher("/public/**")
    );
    private static final RequestMatcher PROTECTED_URLS = new NegatedRequestMatcher(PUBLIC_URLS);

    @Autowired
    TokenAuthenticationProvider provider;

    SecurityConfig() {
        super();
        System.out.println("XXXXXXXXXXXX");
        System.out.println("XXXXXXXXXXXX");
        //this.provider = requireNonNull(provider);
    }

    @Override
    protected void configure(final AuthenticationManagerBuilder auth) {
        auth.authenticationProvider(provider);
    }

    @Override
    public void configure(final WebSecurity web) {
        web.ignoring().requestMatchers(PUBLIC_URLS);
    }

    @Override
    protected void configure(final HttpSecurity http) throws Exception {
        http
                .sessionManagement()
                .sessionCreationPolicy(STATELESS)
                .and()
                .exceptionHandling()
                // this entry point handles when you request a protected page and you are not yet
                // authenticated
                .defaultAuthenticationEntryPointFor(forbiddenEntryPoint(), PROTECTED_URLS)
                .and()
                .authenticationProvider(provider)
                .addFilterBefore(restAuthenticationFilter(), AnonymousAuthenticationFilter.class)
                .authorizeRequests()
                .requestMatchers(PROTECTED_URLS)
                .authenticated()
                .and()
                .csrf().disable()
                .formLogin().disable()
                .httpBasic().disable()
                .logout().disable();
    }

    @Bean
    TokenAuthenticationProvider tokenAuthenticationProvider() {
        return new TokenAuthenticationProvider();
    }

    @Bean
    TokenAuthenticationFilter restAuthenticationFilter() throws Exception {
        final TokenAuthenticationFilter filter = new TokenAuthenticationFilter(PROTECTED_URLS);
        filter.setAuthenticationManager(authenticationManager());
        filter.setAuthenticationSuccessHandler(successHandler());
        return filter;
    }

    @Bean
    SimpleUrlAuthenticationSuccessHandler successHandler() {
        final SimpleUrlAuthenticationSuccessHandler successHandler = new SimpleUrlAuthenticationSuccessHandler();
        successHandler.setRedirectStrategy(new NoRedirectStrategy());
        return successHandler;
    }

    /**
     * Disable Spring boot automatic filter registration.
     */
    @Bean
    FilterRegistrationBean disableAutoRegistration(final TokenAuthenticationFilter filter) {
        final FilterRegistrationBean registration = new FilterRegistrationBean(filter);
        registration.setEnabled(false);
        return registration;
    }

    @Bean
    AuthenticationEntryPoint forbiddenEntryPoint() {
        return new HttpStatusEntryPoint(FORBIDDEN);
    }
}

所以现在我有负责注册和登录的公共(public)端点,但我无法通过 Postman 和浏览器访问它们。 实现这个配置类有问题吗?什么可能导致此问题?

最佳答案

对可公开访问的端点使用configure(WebSecurity web),它不会将安全过滤器链应用于指定的端点。

@Override
    public void configure(WebSecurity web) throws Exception {
        web
          .ignoring()
            .antMatchers("/public/**")
    }

或者尝试更改 configure(final HttpSecurity http) 的顺序。在过滤器和入口点之前添加 .requestMatchers(PROTECTED_URLS)

@Override
    protected void configure(final HttpSecurity http) throws Exception {
        http
        .csrf().disable()
        .authorizeRequests()
        .requestMatchers(PROTECTED_URLS)
        .authenticated()
        .and()
        .exceptionHandling()
        .defaultAuthenticationEntryPointFor(forbiddenEntryPoint(), PROTECTED_URLS)
        .and()
        .sessionManagement()
        .sessionCreationPolicy(STATELESS)
        .and()
        .authenticationProvider(provider)
        .addFilterBefore(restAuthenticationFilter(), AnonymousAuthenticationFilter.class)
        .formLogin().disable()
        .httpBasic().disable()
        .logout().disable();
    }

关于java - 公共(public)端点上的 Spring Boot REST API 401?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59804890/

相关文章:

java - 如何知道为什么我的tomcat被内核杀死

spring - 如何将包含冒号的 URL 映射到 Spring Controller ?

java - Spring MVC 2 中的响应主体

REST 和 DELETE -> 传递参数

java - 这个构造函数是如何工作的?

java - 使用 Apache PDFBox 将实心圆添加到 PDF 页面

java - 如何解决界面中似乎需要 setter 的情况?

java - org.springframework.jdbc.CannotGetJdbcConnectionException : java. sql.SQLException: 找不到适合 jdbc:mysql 的驱动程序

security - Grails LDAP身份验证失败

mysql - Ionic-Angularjs-Restful-webService 项目结构