I have a multi module project, I noticed that when I run my tests (for example the tests annotated with @WebMvcTest
) I get this message
Using generated security password: 12e4c462-385v-12y6-917u-e8u5rte36ooi
This generated password is for development use only. Your security configuration must be updated before running your application in production.
How do i remove it?
I think the "problem" is just that having a multi module project, in some tests, the class implementing UserDetailsService
is not found because it is part of a different module and therefore the package is not scanned.
Is it enough for me to just ignore the message?
Actually this didn't happen before, it has happened since I removed a bean, probably useless, inside the WebSecuriyConfig
class which extends the WebSecurityConfigurerAdapter
.
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
Since I don't use that bean anywhere in my application.
CodePudding user response:
The message you're facing is from spring-boot autoconfiguration class - UserDetailsServiceAutoConfiguration
.
It creates and configures InMemoryUserDetailsManager
if no beans of types AuthenticationManager
, AuthenticationProvider
, UserDetailsService
, AuthenticationManagerResolver
and some other oauth2 and saml2-related beans found in application context.
As clearly stated in this message, it's considered not safe to use this autoconfiguration feature in production, because there's a chance someone will be able to access secured endpoints using default "user" username and password you're seeing (in case it's stolen or exposed).
To disable this autoconfiguration feature try this:
@SpringBootApplication(exclude = {UserDetailsServiceAutoConfiguration.class})
CodePudding user response:
Security configuration is not loaded by default by @WebMvcTest
. You need to manually @Import
your web-security config and then setup test security-context.
For configuring OAuth2 test security context, you can use either
- MockMvc request post-processor:
jwt()
oropaqueToken()
fromorg.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors
) - a test annotation from this repo
Sample with @WithMockJwtAuth
@WebMvcTest()
@Import({ WebSecurityConfig.class })
class GreetingControllerTest {
@MockBean
JwtDecoder jwtDecoder;
@Autowired
MockMvc mockMvc;
@Test
@WithMockJwtAuth(authorities = {"NICE", "AUTHOR"}, claims = @OpenIdClaims(preferred_username = "Tonton Pirate"))
void whenGrantedNiceRoleThenOk() throws Exception {
mockMvc.perform(get("/greet")).andExpect(status().isOk())
.andExpect(content().string("Hi Tonton Pirate! You are granted with: [NICE, AUTHOR]."));
}
@Test
@WithMockJwtAuth(authorities = {"AUTHOR"}, claims = @OpenIdClaims(preferred_username = "Tonton Pirate"))
void whenNotGrantedNiceRoleThenForbidden() throws Exception {
mockMvc.perform(get("/greet")).andExpect(status().isForbidden());
}
@Test
void whenAnonymousThenUnauthorized() throws Exception {
mockMvc.perform(get("/greet")).andExpect(status().isUnauthorized());
}
}
Same sample with jwt
post-processor
@WebMvcTest()
@Import({ WebSecurityConfig.class })
class GreetingControllerTest {
@MockBean
JwtDecoder jwtDecoder;
@Autowired
MockMvc mockMvc;
@Test
void whenGrantedNiceRoleThenOk() throws Exception {
mockMvc.perform(get("/greet").with(jwt().jwt(jwt -> {
jwt.claim("preferred_username", "Tonton Pirate");
}).authorities(List.of(new SimpleGrantedAuthority("NICE"), new SimpleGrantedAuthority("AUTHOR"))))).andExpect(status().isOk())
.andExpect(content().string("Hi Tonton Pirate! You are granted with: [NICE, AUTHOR]."));
}
@Test
void whenNotGrantedNiceRoleThenForbidden() throws Exception {
mockMvc.perform(get("/greet").with(jwt().jwt(jwt -> {
jwt.claim("preferred_username", "Tonton Pirate");
}).authorities(List.of(new SimpleGrantedAuthority("AUTHOR"))))).andExpect(status().isForbidden());
}
@Test
void whenAnonymousThenUnauthorized() throws Exception {
mockMvc.perform(get("/greet")).andExpect(status().isUnauthorized());
}
}