【问题标题】:Resource server test fails with Auth0 issuer uri资源服务器测试因 Auth0 颁发者 uri 而失败
【发布时间】:2021-07-14 05:15:11
【问题描述】:

我创建了一个简单的例子,只充当资源服务器为客户端提供API。

完整的代码可以在Github - hantsy/spring-webmvc-auth0-sample找到。

我浏览过Spring security samples,它使用了jwk-set-uri,在我的应用程序中,我使用了issuer-uri

  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: <auth0 provided issuer uri>

我关注了Auth0 Spring security 5 API Guide ,添加了观众声明验证。

我尝试使用 MockMVC 添加ApplicationTests


    @Test
    public void testGetById() throws Exception {
        Post post = Post.builder().title("test").content("test content").build();
        post.setId(1L);
        given(this.posts.findById(anyLong())).willReturn(Optional.of(post));

        this.mockMvc
                .perform(
                        get("/posts/{id}", 1L)
                                .accept(MediaType.APPLICATION_JSON)
                )
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.name").value("test"));

        verify(this.posts, times(1)).findById(any(Long.class));
        verifyNoMoreInteractions(this.posts);
    }

我的安全配置与此类似。

    @Bean
    SecurityFilterChain springWebFilterChain(HttpSecurity http) throws Exception {
        return http
                .httpBasic(AbstractHttpConfigurer::disable)
                .csrf(AbstractHttpConfigurer::disable)
                .sessionManagement(c -> c.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                .authorizeRequests(c -> c
                        .antMatchers("/", "/info").permitAll()
                        .antMatchers(HttpMethod.GET, "/posts/**").permitAll()//.hasAuthority("SCOPE_read:posts")
                        .antMatchers(HttpMethod.POST, "/posts/**").hasAuthority("SCOPE_write:posts")
                        .antMatchers(HttpMethod.PUT, "/posts/**").hasAuthority("SCOPE_write:posts")
                        .antMatchers(HttpMethod.DELETE, "/posts/**").hasAuthority("SCOPE_delete:posts")
                        .anyRequest().authenticated()
                )
                .oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt)
                .cors().and().build();
    }

运行测试时。

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.NullPointerException: Cannot invoke "org.springframework.test.web.servlet.DefaultMvcResult.setHandler(Object)" because "mvcResult" is null

    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)

我不知道哪里错了?我查看了官方示例,它包含一个 spring.factories file 来启用模拟服务器环境,它是 Spring Boot 中的要求吗?

【问题讨论】:

    标签: spring-boot spring-mvc oauth-2.0 openid-connect auth0


    【解决方案1】:

    问题似乎是在配置中包含cors()

    Spring Security 的CorsFilter 默认代表HandlerMappingInterceptor,它将请求包装在一个专门的HttpServletRequestWrapper 中。当与RouterFunctions 结合使用时,MockMvcMVC_REQUEST_ATTRIBUTE 请求属性将被移除。

    因此,一个解决方法是从您的配置中删除 cors()。事实上,当我从您的样本中删除它时,测试会按预期运行。

    另一个是不使用HandlerMappingInterceptor 默认值。相反,您可以发布自己的CorsConfigurationSource,如下所示:

    @Bean
    CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();    
        configuration.setAllowedOrigins(Arrays.asList("https://example.com"));
        configuration.setAllowedMethods(Arrays.asList("GET","POST"));
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }
    

    在您的示例应用中,当我将上述内容添加到您的 SecurityConfig 时,测试再次按预期运行。

    似乎有一种方法可以调整HandlerMappingIntrospector 中的这个专门的包装器,以免意外删除MVC_REQUEST_ATTRIBUTE,但如果需要任何调整,the Spring Framework team 可能会有更多发言权。我已经在那里提交了a ticket,看看是否有什么可以做的。

    【讨论】:

      猜你喜欢
      • 2022-06-24
      • 2021-06-18
      • 2020-03-14
      • 2011-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-06
      • 2015-09-09
      相关资源
      最近更新 更多