Skip to content
This repository has been archived by the owner on Jan 12, 2024. It is now read-only.

Commit

Permalink
Feat/add cors config (#1163)
Browse files Browse the repository at this point in the history
* Added CORS filter

* Allow OPTIONS without auth

* Broadened CORS pattern

* Removed default CORS allow

* Added some tests for WebSecurityConfiguration

* Fixed spotbugs error

* Closed more things down in CORS if no pattern is set

---------

Co-authored-by: Shawn Sherwood <[email protected]>
  • Loading branch information
shawn-sher and shawn-sher authored May 4, 2023
1 parent e0225ee commit 9ba7647
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,18 @@

package com.nike.cerberus.security;

import static org.apache.commons.lang3.StringUtils.isBlank;

import com.nike.cerberus.service.AuthTokenService;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.List;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
Expand All @@ -35,6 +40,9 @@
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.OrRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

@Slf4j
@Configuration
Expand All @@ -45,6 +53,9 @@ public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
static final String HEADER_X_CERBERUS_TOKEN = "X-Cerberus-Token";
static final String LEGACY_AUTH_TOKN_HEADER = "X-Vault-Token";

@Value("${cerberus.cors.allowedOriginPattern:#{null}}")
private String allowedOriginPattern;

private static final List<String> AUTHENTICATION_NOT_REQUIRED_WHITELIST =
List.of(
"/",
Expand All @@ -68,6 +79,10 @@ public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

@Autowired HttpFirewall allowUrlEncodedSlashHttpFirewall;

void setAllowedOriginPattern(String allowedPattern) {
this.allowedOriginPattern = allowedPattern;
}

RequestMatcher getDoesRequestsRequireAuthMatcher() {

List<RequestMatcher> whiteListMatchers =
Expand Down Expand Up @@ -112,6 +127,9 @@ protected void configure(HttpSecurity http) throws Exception {
.antMatchers(AUTHENTICATION_NOT_REQUIRED_WHITELIST.toArray(new String[0]))
.permitAll();

// ALlow OPTIONS for CORS
http.authorizeRequests().antMatchers(HttpMethod.OPTIONS, "**").permitAll();

// Force all other requests to be authenticated
http.authorizeRequests().anyRequest().authenticated();

Expand All @@ -123,4 +141,28 @@ protected void configure(HttpSecurity http) throws Exception {

http.addFilterBefore(jwtFilter, dbTokenFilter.getClass());
}

@Bean
CorsFilter corsFilter() {
CorsConfiguration config = new CorsConfiguration();
UrlBasedCorsConfigurationSource source = getConfigurationSource(config);
return new CorsFilter(source);
}

UrlBasedCorsConfigurationSource getConfigurationSource(CorsConfiguration config) {
config.setAllowCredentials(false);
config.setAllowedOrigins(null);
if (!isBlank(allowedOriginPattern)) {
config.addAllowedOriginPattern(allowedOriginPattern);
config.addAllowedHeader("*");
config.addAllowedMethod("*");
} else {
config.setAllowedOriginPatterns(null);
config.setAllowedHeaders(null);
config.setAllowedMethods(null);
}
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return source;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.nike.cerberus.security;

import java.util.List;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.web.cors.CorsConfiguration;

public class WebSecurityConfigurationTest {

@Test
public void testNoAllowedOriginPattern() {
WebSecurityConfiguration wsc = new WebSecurityConfiguration();
CorsConfiguration config = new CorsConfiguration();
wsc.getConfigurationSource(config);
Assert.assertEquals(config.getAllowedOriginPatterns(), null);
Assert.assertEquals(config.getAllowedOrigins(), null);
Assert.assertEquals(config.getAllowedHeaders(), null);
Assert.assertEquals(config.getAllowedMethods(), null);
Assert.assertFalse(config.getAllowCredentials());
}

@Test
public void testCustomAllowedOriginPattern() {
WebSecurityConfiguration wsc = new WebSecurityConfiguration();
wsc.setAllowedOriginPattern("https://*.testdomain.com");
CorsConfiguration config = new CorsConfiguration();
wsc.getConfigurationSource(config);
Assert.assertEquals(config.getAllowedOriginPatterns(), List.of("https://*.testdomain.com"));
Assert.assertEquals(config.getAllowedOrigins(), null);
Assert.assertEquals(config.getAllowedHeaders(), List.of("*"));
Assert.assertEquals(config.getAllowedMethods(), List.of("*"));
Assert.assertFalse(config.getAllowCredentials());
}
}

0 comments on commit 9ba7647

Please sign in to comment.