Thank you for this project. It is just what I needed for my @WebMvcTest tests in my Spring Boot project. I am using Spring Boot 2.2.6 with keycloak-spring-boot-starter 9.0.0.
After adding:
<dependency>
<groupId>com.c4-soft.springaddons</groupId>
<artifactId>spring-security-oauth2-test-webmvc-addons</artifactId>
<version>2.0.0</version>
<scope>test</scope>
</dependency>
to my project, I also had to do the following things:
- Create a custom meta-annotation for all my webmvc tests:
@Retention(RetentionPolicy.RUNTIME)
@WebMvcTest
@ContextConfiguration(classes = MyProjectRestControllerTestConfiguration.class)
@ActiveProfiles("webmvc-test")
public @interface MyProjectRestControllerTest {
/**
* @see WebMvcTest#value
*/
@AliasFor(annotation = WebMvcTest.class, attribute = "value")
Class<?>[] value() default {};
/**
* @see WebMvcTest#controllers
*/
@AliasFor(annotation = WebMvcTest.class, attribute = "controllers")
Class<?>[] controllers() default {};
}
- I created a custom
@TestConfiguration for my test:
@TestConfiguration
@Import({KeycloakAutoConfiguration.class, WebSecurityConfiguration.class})
public class MyProjectRestControllerTestConfiguration {
@Bean
public KeycloakSpringBootConfigResolver keycloakSpringBootConfigResolver() {
return new KeycloakSpringBootConfigResolver();
}
}
Where WebSecurityConfiguration is my actual production security config class:
@KeycloakConfiguration
public class WebSecurityConfiguration extends KeycloakWebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder builder) {
KeycloakAuthenticationProvider provider = new KeycloakAuthenticationProvider();
provider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
builder.authenticationProvider(provider);
}
@Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.authorizeRequests()
.requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
.antMatchers("/actuator/info", "/actuator/health").permitAll()
.anyRequest()
.hasRole("user");
}
}
- Next, I added
application-webmvc-test.properties in src/test/resources:
# Properties are here for proper startup. Keycloak is not actually used in @WebMvcTest tests
keycloak.auth-server-url=http://localhost:8180/auth
keycloak.realm=pegus-digital-test
keycloak.resource=springboot-app
keycloak.public-client=true
keycloak.principal-attribute=preferred_username
- Finally my test self:
@MyProjectRestControllerTest(UserRestController.class)
class UserRestControllerTest {
@Autowired
private MockMvc mockMvc;
@Test
void testOwnUserDetails() throws Exception {
KeycloakAuthRequestPostProcessor keycloakAuthRequestPostProcessor = new KeycloakAuthRequestPostProcessor()
.roles("user", "admin")
.name("wim.deblauwe@example.com")
.idToken(idToken -> {
idToken.setSubject("aac53545-5d5b-4e1f-8c94-0c593d22b5a2");
idToken.setGivenName("Wim");
idToken.setFamilyName("Deblauwe");
});
mockMvc.perform(get("/api/users/me")
.with(keycloakAuthRequestPostProcessor))
.andExpect(status().isOk())
.andExpect(jsonPath("authorizationServerUserId").value("aac53545-5d5b-4e1f-8c94-0c593d22b5a2"))
.andExpect(jsonPath("firstName").value("Wim"))
.andExpect(jsonPath("lastName").value("Deblauwe"))
.andExpect(jsonPath("email").value("wim.deblauwe@example.com"))
.andExpect(jsonPath("userRole").value("ADMIN"))
;
}
}
Might be good to add something similar to the documentation, as most people will have Keycloak on the classpath in their project (unlike the example in your repo currently).
Thank you for this project. It is just what I needed for my
@WebMvcTesttests in my Spring Boot project. I am using Spring Boot 2.2.6 withkeycloak-spring-boot-starter9.0.0.After adding:
to my project, I also had to do the following things:
@TestConfigurationfor my test:Where
WebSecurityConfigurationis my actual production security config class:application-webmvc-test.propertiesinsrc/test/resources:Might be good to add something similar to the documentation, as most people will have Keycloak on the classpath in their project (unlike the example in your repo currently).