首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用Spring Security OAuth测试Spring rest控制器

用Spring Security OAuth测试Spring rest控制器
EN

Stack Overflow用户
提问于 2020-08-18 00:41:19
回答 1查看 145关注 0票数 0

我正在尝试用Spring boot @WebMvcTest测试我的控制器。我还实现了SPring OAuth安全性(资源和授权服务器),因此您需要获得授权才能到达端点。

由于这个原因,我不能像这样测试我的控制器:

代码语言:javascript
运行
复制
@WebMvcTest(MyController.class)
public class MyControllerTest {

    @Autowired
    private MockMvc mvc;

    @Autowired
    private ObjectMapper objectMapper;

    @MockBean
    private MyService service;

    @Test
    public void myTest() throws Exception {
        //Arrange request
        
        //Act
        mvc.perform
            (MockMvcRequestBuilders
                .post("/v1/my-controller/type", type.name())
                .characterEncoding(StandardCharsets.UTF_8.name())
                .contentType(MediaType.APPLICATION_JSON)
                .content(objectMapper.writeValueAsString(requestDTO)))
            //Assert
            .andExpect(status().isOk())
            .andExpect(content().contentType(MediaType.APPLICATION_JSON))
            .andExpect(content().json(objectMapper.writeValueAsString("")));

    }

因为它需要资源服务器。但问题是,当我运行这个测试时,我得到了下一个错误:

代码语言:javascript
运行
复制
    ***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 0 of constructor in com.danfoss.cloud.prosa.restapi.security.WebSecurityConfig$OAuthResourceServer required a bean of type 'org.springframework.security.oauth2.provider.token.TokenStore' that could not be found.


Action:

Consider defining a bean of type 'org.springframework.security.oauth2.provider.token.TokenStore' in your configuration.

我的资源服务器看起来像

代码语言:javascript
运行
复制
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Configuration
    @EnableResourceServer
    public static class OAuthResourceServer extends ResourceServerConfigurerAdapter {

         
        private final TokenStore tokenStore;
        ////CANNOT INJECT DURING WEB CONTEXT START
        @Autowired
        public OAuthResourceServer(TokenStore tokenStore) {
            this.tokenStore = tokenStore;
        }

        @Override
        public void configure(ResourceServerSecurityConfigurer resources) {
            resources
                    .resourceId("resource")
                    .tokenStore(tokenStore);
        }

        @Override
        public void configure(HttpSecurity http) throws Exception {
            http
                .authorizeRequests()
                .antMatchers("/status")
                .permitAll()
                .anyRequest()
                .access("isAuthenticated()");
        }

        private String createAuthorizationExpression(String ipWhitelist) {
            return null;
        }
    }
}

重要的一点是,应用程序运行良好,并且在运行期间可以很好地注入TokenStore。

如何克服这个问题?

EN

回答 1

Stack Overflow用户

发布于 2020-08-19 19:18:23

通过像这样解耦配置解决了这个问题:

代码语言:javascript
运行
复制
@Configuration
public class Config {

    @Bean
    public TokenStore tokenStore() {
        return new JdbcTokenStore(mainDataSource());
    }

               ....
    other beans
}

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
}

@Configuration
@EnableWebSecurity
@EnableResourceServer
public class OAuthResourceServer extends ResourceServerConfigurerAdapter {

    private final TokenStore tokenStore;


    @Autowired
    public OAuthResourceServer(TokenStore tokenStore) {
        this.tokenStore = tokenStore;
    }

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) {
        resources
            .resourceId("resource")
            .tokenStore(tokenStore);
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
            .antMatchers(
                "/status",
                "/")
            .permitAll()
            .anyRequest()
            .access(
                            ...
                        );
    }


}

@Configuration
@EnableAuthorizationServer
public class OAuthAuthorizationServer extends AuthorizationServerConfigurerAdapter {

        ...
    private final AuthenticationManager authenticationManager;
      ...
    private final TokenStore tokenStore;
     ...


    @Autowired
    public OAuthAuthorizationServer(
    ....
        AuthenticationManager authenticationManager,
        TokenStore tokenStore,
    ...
    ) {
        this.restUserDetailsService = restUserDetailsService;
        this.oAuthRestAuthenticationProvider = oAuthRestAuthenticationProvider;
        this.authenticationManager = authenticationManager;
        this.jdbcClientDetailsService = jdbcClientDetailsService;
        this.tokenStore = tokenStore;
        this.authorizationCodeServices = authorizationCodeServices;
    }

    @Bean
    public AuthorizationServerTokenServices tokenServices() {
        DefaultTokenServices tokenServices = new DefaultTokenServices();
        tokenServices.setAccessTokenValiditySeconds(accessTokenValiditySeconds);
        tokenServices.setRefreshTokenValiditySeconds(refreshTokenValiditySeconds);
        tokenServices.setSupportRefreshToken(true);
        tokenServices.setReuseRefreshToken(true);
        tokenServices.setTokenStore(tokenStore);
        tokenServices.setClientDetailsService(jdbcClientDetailsService);
        tokenServices.setSupportRefreshToken(true);
        tokenServices.setAuthenticationManager(authenticationManager);
        return tokenServices;
    }

    @Autowired
    public void configure(AuthenticationManagerBuilder auth) {
        auth.authenticationProvider(oAuthRestAuthenticationProvider);
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.withClientDetails(jdbcClientDetailsService);
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
        endpoints
            .approvalStoreDisabled()
            .authorizationCodeServices(authorizationCodeServices)
            .tokenStore(tokenStore)
            .tokenServices(tokenServices())
            .authenticationManager(authenticationManager)
            .userDetailsService(restUserDetailsService);
    }
}

然后,要在控制器测试中禁用安全性,需要执行下一步操作

代码语言:javascript
运行
复制
@WebMvcTest(MyController.class)
@AutoConfigureMockMvc(addFilters = false)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63455088

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档