5

среды: У меня есть на основе пружинных загрузок приложения microservice архитектуры, состоящее из нескольких инфраструктурных услуг и услуг ресурсов (содержащей бизнес-логику). Авторизация и аутентификация обрабатываются службой oAuth2-Service, управляющей пользовательскими объектами, и созданием токенов JWT для клиентов.Использование @WithMockUser (с @SpringBootTest) внутри oauth2 ресурсов сервера приложения

Для проверки одного приложения microservice в целом я пытался построить тесты с TestNG, spring.boot.test, org.springframework.security.test ...

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK, properties = {"spring.cloud.discovery.enabled=false", "spring.cloud.config.enabled=false", "spring.profiles.active=test"}) 
@AutoConfigureMockMvc 
@Test 
public class ArtistControllerTest extends AbstractTestNGSpringContextTests { 

    @Autowired 
    private MockMvc mvc; 

    @BeforeClass 
    @Transactional 
    public void setUp() { 
    // nothing to do 
    } 

    @AfterClass 
    @Transactional 
    public void tearDown() { 
    // nothing to do here 
    } 

    @Test 
    @WithMockUser(authorities = {"READ", "WRITE"}) 
    public void getAllTest() throws Exception { 

    // EXPECT HTTP STATUS 200 
    // BUT GET 401 
    this.mvc.perform(get("/") 
      .accept(MediaType.APPLICATION_JSON)) 
      .andExpect(status().isOk()) 
    } 
} 

где конфигурацией безопасности (ресурсного сервера) является следующее:

@Configuration 
@EnableResourceServer 
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter { 

    // get the configured token store 
    @Autowired 
    TokenStore tokenStore; 

    // get the configured token converter 
    @Autowired 
    JwtAccessTokenConverter tokenConverter; 

    /** 
    * !!! configuration of springs http security !!! 
    */ 
    @Override 
    public void configure(HttpSecurity http) throws Exception { 
     http 
      .csrf().disable() 
      .authorizeRequests() 
      .antMatchers("/**").authenticated(); 
    } 

    /** 
    * configuration of springs resource server security 
    */ 
    @Override 
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception { 
    // set the configured tokenStore to this resourceServer 
    resources.resourceId("artist").tokenStore(tokenStore); 
    } 

} 

и следующий метод основан на проверке безопасности аннотированных ins Ide класса контроллера

@PreAuthorize("hasAuthority('READ')") 
@RequestMapping(value = "/", method = RequestMethod.GET) 
public List<Foo> getAll(Principal user) { 
    List<Foo> foos = fooRepository.findAll(); 
    return foos; 
} 

я думал, что будет работать, но при запуске теста я только получаю сообщение об ошибке утверждения

java.lang.AssertionError: Status 
Expected :200 
Actual :401 


Вопрос: Есть ли что-то совершенно очевидно, что я делаю неправильно? Или @WithMockUser не собирается работать с @SpringBootTest и @AutoConfigureMockMvc в среде oAuth2? Если это так ... Каким будет наилучший подход для тестирования конфигураций безопасности на основе маршрутов и методов как часть такого (интеграционного) теста, подобного этому?


Приложение: Я также пробовал различные подходы, как что-то вроде следующего ... но это привело к тому же результату :(

this.mvc.perform(get("/") 
     .with(user("admin").roles("READ","WRITE").authorities(() -> "READ",() -> "WRITE")) 
     .accept(MediaType.APPLICATION_JSON)) 

см:
spring security testing
spring boot 1.4 testing

ответ

4

@WithMockUser создает аутентификацию в SecurityContext. То же самое относится к with(user("username")).

По умолчанию OAuth2AuthenticationProcessingFilter не использует SecurityContext, но всегда создает аутентификацию из токена («без гражданства»).

Вы можете легко изменить это поведение будет установка лица без флага в конфигурации системы безопасности сервера ресурса ложный:

@Configuration 
@EnableResourceServer 
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter { 

    @Override 
    public void configure(ResourceServerSecurityConfigurer security) throws Exception { 
     security.stateless(false); 
    } 
} 

Конечно, установить флаг в тестовых условиях ложной, только.

+0

Добавление этого класса в мой проект maven/java работает для меня с Spring Boot 1.5.4 и 1.5.9. Теперь я могу использовать user @WithMockUser, как я ожидал. – DaShaun

+0

Добавление этого класса в мой проект позволяет обойти систему безопасности, но это не похоже на вопрос пользователя. Он всегда передает безопасность независимо от того, какую область я предоставляю своим тестовым пользователям. Это намерение? – Rig

2

У меня был de sa мне вопрос, и единственный способ, которым я нашел было создать маркер и использовать его в mockMvc выполнить

mockMvc.perform(get("/resource") 
        .with(oAuthHelper.bearerToken("test")) 

И в OAuthHelper:

@Component 
@EnableAuthorizationServer 
public class OAuthHelper extends AuthorizationServerConfigurerAdapter { 

    @Autowired 
    AuthorizationServerTokenServices tokenservice; 

    @Autowired 
    ClientDetailsService clientDetailsService; 

    public RequestPostProcessor bearerToken(final String clientid) { 
     return mockRequest -> { 
      OAuth2AccessToken token = createAccessToken(clientid); 
      mockRequest.addHeader("Authorization", "Bearer " + token.getValue()); 
      return mockRequest; 
     }; 
    } 

    OAuth2AccessToken createAccessToken(final String clientId) { 
     ClientDetails client = clientDetailsService.loadClientByClientId(clientId); 
     Collection<GrantedAuthority> authorities = client.getAuthorities(); 
     Set<String> resourceIds = client.getResourceIds(); 
     Set<String> scopes = client.getScope(); 

     Map<String, String> requestParameters = Collections.emptyMap(); 
     boolean approved = true; 
     String redirectUrl = null; 
     Set<String> responseTypes = Collections.emptySet(); 
     Map<String, Serializable> extensionProperties = Collections.emptyMap(); 

     OAuth2Request oAuth2Request = new OAuth2Request(requestParameters, clientId, authorities, 
       approved, scopes, resourceIds, redirectUrl, responseTypes, extensionProperties); 

     User userPrincipal = new User("user", "", true, true, true, true, authorities); 
     UsernamePasswordAuthenticationToken authenticationToken = 
       new UsernamePasswordAuthenticationToken(userPrincipal, null, authorities); 
     OAuth2Authentication auth = new OAuth2Authentication(oAuth2Request, authenticationToken); 

     return tokenservice.createAccessToken(auth); 
    } 

    @Override 
    public void configure(final ClientDetailsServiceConfigurer clients) throws Exception { 
     clients.inMemory() 
       .withClient("test") 
       .authorities("READ"); 
    } 

} 
+1

проблема заключается в том, что моя служба безопасности, которая создает маркеры в производстве, является другим микросервисом, чем тот, который использует токен для проверки авторизации и аутентификации ... и с его токена JWT он использует файл закрытого ключа для создания токен, и я не хочу иметь закрытый токен, распространяемый по всем моим ресурсным микросервисам. или я получаю что-то неправильно? – David

+0

Да, у меня такой же дизайн, поэтому для проверки микросервиса, который раскрывает ресурсы, я сделал это в тестах –

+0

У меня также есть приватный ключ в службе auth и ключ в другом микросервисе –

 Смежные вопросы

  • Нет связанных вопросов^_^