Skip to content

Commit

Permalink
Cors configuration & actuator test fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
andreaceccanti committed Oct 26, 2021
1 parent 4ed75ff commit 4a70982
Show file tree
Hide file tree
Showing 12 changed files with 114 additions and 100 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ public class IamHealthConfiguration {
private HealthAggregator healthAggregator = new OrderedHealthAggregator();

@Autowired
DataSource dataSource;
private DataSource dataSource;

@Autowired
DiskSpaceHealthIndicatorProperties properties;
private DiskSpaceHealthIndicatorProperties properties;

@Bean
public HealthEndpoint healthEndpoint() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,15 +74,17 @@ private HttpStatus getStatus(Health health) {
private Health getHealth(AbstractAuthenticationToken auth) {
Health health = getDelegate().invoke();

if (auth != null && isAdmin(auth.getAuthorities())) {
if (auth != null && isAdminOrActuator(auth.getAuthorities())) {
return health;
}
return Health.status(health.getStatus()).build();
}

private boolean isAdmin(Collection<GrantedAuthority> authorities) {
private boolean isAdminOrActuator(Collection<GrantedAuthority> authorities) {

for (GrantedAuthority authority : authorities) {
if ("ROLE_ADMIN".equals(authority.getAuthority())) {
if ("ROLE_ACTUATOR".equals(authority.getAuthority())
|| "ROLE_ADMIN".equals(authority.getAuthority())) {
return true;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -267,4 +267,5 @@ ServletRegistrationBean h2Console() {
VelocityEngine velocityEngine() {
return new VelocityEngine();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package it.infn.mw.iam.config.security;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

@Configuration
public class CorsConfig {

private static final String[] CORS_ENDPOINT_MATCHERS =
// @formatter:off
{
"/api/**",
"/resource/**",
"/register/**",
"/iam/**",
"/scim/**",
"/token",
"/introspect",
"/userinfo",
"/revoke/**",
"/jwk",
"/devicode"
};
//@formatter:on

@Bean
CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration corsConfig = new CorsConfiguration();
corsConfig.applyPermitDefaultValues();

for (String m : CORS_ENDPOINT_MATCHERS) {
source.registerCorsConfiguration(m, corsConfig);
}

return new CorsFilter(source);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
Expand All @@ -36,6 +35,7 @@

import it.infn.mw.iam.api.proxy.ProxyCertificatesApiController;
import it.infn.mw.iam.config.CustomAuthenticationEntryPoint;
import it.infn.mw.iam.config.IamProperties;
import it.infn.mw.iam.core.oauth.FormClientCredentialsAuthenticationFilter;

@Configuration
Expand Down Expand Up @@ -68,9 +68,9 @@ protected void configure(final HttpSecurity http) throws Exception {
FormClientCredentialsAuthenticationFilter ccFilter =
new FormClientCredentialsAuthenticationFilter(PROXY_API_MATCHER,
authenticationEntryPoint);

ccFilter.setAuthenticationManager(authenticationManager());

// @formatter:off
http.antMatcher(PROXY_API_MATCHER)
.exceptionHandling()
Expand Down Expand Up @@ -103,7 +103,7 @@ public static class IamApiConfig extends WebSecurityConfigurerAdapter {

@Autowired
private OAuth2AuthenticationEntryPoint authenticationEntryPoint;

@Override
protected void configure(final HttpSecurity http) throws Exception {
// @formatter:off
Expand Down Expand Up @@ -145,11 +145,8 @@ protected void configure(final HttpSecurity http) throws Exception {
@Order(25)
public static class ActuatorEndpointsConfig extends WebSecurityConfigurerAdapter {

@Value("${iam.superuser.username}")
private String basicUsername;

@Value("${iam.superuser.password}")
private String basicPassword;
@Autowired
private IamProperties properties;

@Autowired
private OAuth2AuthenticationProcessingFilter resourceFilter;
Expand All @@ -161,8 +158,8 @@ public static class ActuatorEndpointsConfig extends WebSecurityConfigurerAdapter
public void configure(AuthenticationManagerBuilder auth) throws Exception {
// @formatter:off
auth.inMemoryAuthentication()
.withUser(basicUsername).password(basicPassword)
.roles("SUPERUSER", "ADMIN");
.withUser(properties.getSuperuser().getUsername()).password(properties.getSuperuser().getPassword())
.roles("ACTUATOR");
// @formatter:on
}

Expand All @@ -186,9 +183,9 @@ protected void configure(final HttpSecurity http) throws Exception {
.and()
.authorizeRequests()
.antMatchers(GET, "/info", "/health", "/health/mail", "/health/external").permitAll()
.antMatchers(GET, "/metrics").hasRole("ADMIN")
.antMatchers(GET, "/metrics").hasAnyRole("ADMIN", "ACTUATOR")
.antMatchers(GET, "/configprops", "/env", "/mappings",
"/flyway", "/autoconfig", "/beans", "/dump", "/trace").hasRole("SUPERUSER");
"/flyway", "/autoconfig", "/beans", "/dump", "/trace").hasRole("ACTUATOR");
// @formatter:on
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ public void configure(final HttpSecurity http) throws Exception {
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.NEVER)
.and()
.csrf().disable();
.csrf().disable()
.cors();
// @formatter:on

}
Expand Down Expand Up @@ -157,8 +158,10 @@ public void configure(final HttpSecurity http) throws Exception {
.authenticationEntryPoint(authenticationEntryPoint)
.and()
.addFilterAfter(resourceFilter, SecurityContextPersistenceFilter.class)
.sessionManagement()
.sessionCreationPolicy(STATELESS)
.cors()
.and()
.sessionManagement()
.sessionCreationPolicy(STATELESS)
.and()
.csrf().disable();
// @formatter:on
Expand Down Expand Up @@ -189,9 +192,11 @@ protected void configure(final HttpSecurity http) throws Exception {
http.antMatcher("/introspect/**")
.httpBasic()
.authenticationEntryPoint(authenticationEntryPoint)
.and()
.cors()
.and()
.exceptionHandling()
.authenticationEntryPoint(authenticationEntryPoint)
.authenticationEntryPoint(authenticationEntryPoint)
.and()
.sessionManagement()
.sessionCreationPolicy(STATELESS).and()
Expand Down Expand Up @@ -239,6 +244,8 @@ protected void configure(final HttpSecurity http) throws Exception {
.authenticationEntryPoint(authenticationEntryPoint)
.and()
.addFilterBefore(clientCredentialsEndpointFilter(), BasicAuthenticationFilter.class)
.cors()
.and()
.exceptionHandling()
.authenticationEntryPoint(authenticationEntryPoint)
.and()
Expand All @@ -262,6 +269,8 @@ protected void configure(final HttpSecurity http) throws Exception {
http.antMatcher("/jwk**")
.exceptionHandling()
.authenticationEntryPoint(http403ForbiddenEntryPoint)
.and()
.cors()
.and()
.sessionManagement()
.sessionCreationPolicy(STATELESS)
Expand Down
5 changes: 1 addition & 4 deletions iam-login-service/src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,6 @@ spring:
username: ${IAM_MAIL_USERNAME:}
password: ${IAM_MAIL_PASSWORD:}

velocity:
enabled: false

freemarker:
template-loader-path: ${IAM_CUSTOM_TEMPLATE_LOCATION:classpath:templates/}

Expand Down Expand Up @@ -171,7 +168,7 @@ accountLinking:

clientRegistration:
allow-for: ${IAM_CLIENT_REGISTRATION_ALLOW_FOR:ANYONE}

endpoints:
enabled: false
info:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,23 +33,27 @@
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.web.context.WebApplicationContext;

import it.infn.mw.iam.config.IamProperties;
import it.infn.mw.iam.test.util.annotation.IamMockMvcIntegrationTest;

@RunWith(SpringRunner.class)
@IamMockMvcIntegrationTest
@TestPropertySource(properties= {"endpoints.env.enabled=true",
@TestPropertySource(properties = {
// @formatter:off
"endpoints.env.enabled=true",
"endpoints.configprops.enabled=true",
"endpoints.mappings.enabled=true",
"endpoints.flyway.enabled=true",
"endpoints.autoconfig.enabled=true",
"endpoints.beans.enabled=true",
"endpoints.dump.enabled=true",
"endpoints.trace.enabled=true"})
"endpoints.trace.enabled=true"
// @formatter:on
})
public class ActuatorEndpointsTests extends ActuatorTestSupport {


@Value("${health.mailProbe.path}")
private String mailHealthEndpoint;

Expand All @@ -59,14 +63,8 @@ public class ActuatorEndpointsTests extends ActuatorTestSupport {
@Value("${spring.mail.port}")
private Integer mailPort;

@Value("${iam.superuser.username}")
private String basicUsername;

@Value("${iam.superuser.password}")
private String basicPassword;

@Autowired
private WebApplicationContext context;
private IamProperties iamProperties;

@Autowired
private MockMvc mvc;
Expand Down Expand Up @@ -98,7 +96,7 @@ public void testHealthEndpointAsUser() throws Exception {
}

@Test
@WithMockUser(username = ADMIN_USERNAME, roles = {ADMIN_ROLE})
@WithMockUser(username = ADMIN_USERNAME, roles = {ACTUATOR_ROLE})
public void testHealthEndpointAsAdmin() throws Exception {
// @formatter:off
mvc.perform(get("/health"))
Expand All @@ -113,7 +111,8 @@ public void testHealthEndpointAsAdmin() throws Exception {
@Test
public void testHealthEndpointAsSuperUser() throws Exception {
// @formatter:off
mvc.perform(get("/health").with(httpBasic(basicUsername, basicPassword)))
mvc.perform(get("/health").with(httpBasic(iamProperties.getSuperuser().getUsername(),
iamProperties.getSuperuser().getPassword())))
.andExpect(status().isOk())
.andExpect(jsonPath("$.status", equalTo(STATUS_UP)))
.andExpect(jsonPath("$.diskSpace.status", equalTo(STATUS_UP)))
Expand Down Expand Up @@ -146,7 +145,7 @@ public void testInfoEndpointAsUser() throws Exception {
}

@Test
@WithMockUser(username = ADMIN_USERNAME, roles = {ADMIN_ROLE})
@WithMockUser(username = ADMIN_USERNAME, roles = {ACTUATOR_ROLE})
public void testInfoEndpointAsAdmin() throws Exception {
// @formatter:off
mvc.perform(get("/info"))
Expand Down Expand Up @@ -179,7 +178,7 @@ public void testSensitiveEndpointsAsUser() throws Exception {
}

@Test
@WithMockUser(username = ADMIN_USERNAME, roles = {ADMIN_ROLE})
@WithMockUser(username = ADMIN_USERNAME, roles = {ACTUATOR_ROLE})
public void testSensitiveEndpointsAsAdmin() throws Exception {
for (String endpoint : SENSITIVE_ENDPOINTS) {
// @formatter:off
Expand All @@ -193,7 +192,9 @@ public void testSensitiveEndpointsAsAdmin() throws Exception {
public void testSensitiveEndpointsAsSuperUser() throws Exception {
for (String endpoint : SENSITIVE_ENDPOINTS) {
// @formatter:off
mvc.perform(get(endpoint).with(httpBasic(basicUsername, basicPassword)))
mvc.perform(get(endpoint)
.with(httpBasic(iamProperties.getSuperuser().getUsername(),
iamProperties.getSuperuser().getPassword())))
.andExpect(status().isOk());
// @formatter:on
}
Expand Down Expand Up @@ -221,7 +222,7 @@ public void testMailHealthEndpointWithoutSmtpAsUser() throws Exception {
}

@Test
@WithMockUser(username = ADMIN_USERNAME, roles = {ADMIN_ROLE})
@WithMockUser(username = ADMIN_USERNAME, roles = {ACTUATOR_ROLE})
public void testMailHealthEndpointWithoutSmtpAsAdmin() throws Exception {
// @formatter:off
mvc.perform(get(mailHealthEndpoint))
Expand Down Expand Up @@ -259,7 +260,8 @@ public void testPrivilegedEndopointsAsAdmin() throws Exception {
@Test
public void testPrivilegedEndopointsAsSuperUser() throws Exception {
for (String endpoint : PRIVILEGED_ENDPOINTS) {
mvc.perform(get(endpoint).with(httpBasic(basicUsername, basicPassword)))
mvc.perform(get(endpoint).with(httpBasic(iamProperties.getSuperuser().getUsername(),
iamProperties.getSuperuser().getPassword())))
.andExpect(status().isOk());
}
}
Expand Down
Loading

0 comments on commit 4a70982

Please sign in to comment.