generated from bcgov/quickstart-openshift
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(SILVA-514 + sec): fixing favorite name on search result and secur…
…ity update (#491)
- Loading branch information
1 parent
2092be5
commit d7332db
Showing
38 changed files
with
702 additions
and
713 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
50 changes: 35 additions & 15 deletions
50
backend/src/main/java/ca/bc/gov/restapi/results/common/configuration/CorsConfiguration.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,36 +1,56 @@ | ||
package ca.bc.gov.restapi.results.common.configuration; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Arrays; | ||
import java.util.List; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.beans.factory.annotation.Value; | ||
import org.apache.commons.lang3.StringUtils; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.lang.NonNull; | ||
import org.springframework.web.servlet.config.annotation.CorsRegistry; | ||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; | ||
|
||
/** This class holds the configuration for CORS handling. */ | ||
/** | ||
* This class holds the configuration for CORS handling. | ||
*/ | ||
@Slf4j | ||
@Configuration | ||
@RequiredArgsConstructor | ||
public class CorsConfiguration implements WebMvcConfigurer { | ||
|
||
@Value("${server.allowed.cors.origins}") | ||
private String[] allowedOrigins; | ||
private final SilvaConfiguration configuration; | ||
|
||
/** | ||
* Adds CORS mappings and allowed origins. | ||
* | ||
* @param registry Spring Cors Registry | ||
*/ | ||
@Override | ||
public void addCorsMappings(@NonNull CorsRegistry registry) { | ||
if (allowedOrigins != null && allowedOrigins.length != 0) { | ||
log.info("allowedOrigins: {}", Arrays.asList(allowedOrigins)); | ||
var frontendConfig = configuration.getFrontend(); | ||
var cors = frontendConfig.getCors(); | ||
String origins = frontendConfig.getUrl(); | ||
List<String> allowedOrigins = new ArrayList<>(); | ||
|
||
registry | ||
.addMapping("/**") | ||
.allowedOriginPatterns(allowedOrigins) | ||
.allowedMethods("GET", "PUT", "POST", "DELETE", "PATCH", "OPTIONS", "HEAD"); | ||
if (StringUtils.isNotBlank(origins) && origins.contains(",")) { | ||
allowedOrigins.addAll(Arrays.asList(origins.split(","))); | ||
} else { | ||
allowedOrigins.add(origins); | ||
} | ||
|
||
log.info("Allowed origins: {} {}", allowedOrigins,allowedOrigins.toArray(new String[0])); | ||
|
||
registry | ||
.addMapping("/api/**") | ||
.allowedOriginPatterns(allowedOrigins.toArray(new String[0])) | ||
.allowedMethods(cors.getMethods().toArray(new String[0])) | ||
.allowedHeaders(cors.getHeaders().toArray(new String[0])) | ||
.exposedHeaders(cors.getHeaders().toArray(new String[0])) | ||
.maxAge(cors.getAge().getSeconds()) | ||
.allowCredentials(true); | ||
|
||
registry.addMapping("/actuator/**") | ||
.allowedOrigins("*") | ||
.allowedMethods("GET") | ||
.allowedHeaders("*") | ||
.allowCredentials(false); | ||
|
||
WebMvcConfigurer.super.addCorsMappings(registry); | ||
} | ||
} |
81 changes: 17 additions & 64 deletions
81
...d/src/main/java/ca/bc/gov/restapi/results/common/configuration/SecurityConfiguration.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,88 +1,41 @@ | ||
package ca.bc.gov.restapi.results.common.configuration; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Collection; | ||
import java.util.List; | ||
import org.springframework.beans.factory.annotation.Value; | ||
import ca.bc.gov.restapi.results.common.security.ApiAuthorizationCustomizer; | ||
import ca.bc.gov.restapi.results.common.security.CsrfSecurityCustomizer; | ||
import ca.bc.gov.restapi.results.common.security.HeadersSecurityCustomizer; | ||
import ca.bc.gov.restapi.results.common.security.Oauth2SecurityCustomizer; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.core.convert.converter.Converter; | ||
import org.springframework.http.HttpMethod; | ||
import org.springframework.security.authentication.AbstractAuthenticationToken; | ||
import org.springframework.security.config.Customizer; | ||
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; | ||
import org.springframework.security.config.annotation.web.builders.HttpSecurity; | ||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; | ||
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; | ||
import org.springframework.security.core.GrantedAuthority; | ||
import org.springframework.security.core.authority.SimpleGrantedAuthority; | ||
import org.springframework.security.oauth2.jwt.Jwt; | ||
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter; | ||
import org.springframework.security.web.SecurityFilterChain; | ||
import org.springframework.security.web.csrf.CookieCsrfTokenRepository; | ||
|
||
/** This class contains all configurations related to security and authentication. */ | ||
@Configuration | ||
@EnableWebSecurity | ||
@EnableMethodSecurity | ||
public class SecurityConfiguration { | ||
|
||
@Value("${spring.security.oauth2.resourceserver.jwt.jwk-set-uri}") | ||
String jwkSetUri; | ||
|
||
/** | ||
* Filters a request to add security checks and configurations. | ||
* | ||
* @param http instance of HttpSecurity containing the request. | ||
* @return SecurityFilterChain with allowed endpoints and all configuration. | ||
* @throws Exception due to bad configuration possibilities. | ||
*/ | ||
@Bean | ||
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { | ||
http.cors(Customizer.withDefaults()) | ||
.csrf( | ||
customize -> | ||
customize.csrfTokenRepository(new CookieCsrfTokenRepository())) | ||
.authorizeHttpRequests( | ||
customize -> | ||
customize | ||
.requestMatchers("/api/**") | ||
.authenticated() | ||
.requestMatchers(HttpMethod.OPTIONS, "/**") | ||
.permitAll() | ||
.anyRequest() | ||
.permitAll()) | ||
public SecurityFilterChain filterChain( | ||
HttpSecurity http, | ||
HeadersSecurityCustomizer headersCustomizer, | ||
CsrfSecurityCustomizer csrfCustomizer, | ||
ApiAuthorizationCustomizer apiCustomizer, | ||
Oauth2SecurityCustomizer oauth2Customizer | ||
) throws Exception { | ||
http | ||
.headers(headersCustomizer) | ||
.csrf(csrfCustomizer) | ||
.cors(Customizer.withDefaults()) | ||
.authorizeHttpRequests(apiCustomizer) | ||
.httpBasic(AbstractHttpConfigurer::disable) | ||
.formLogin(AbstractHttpConfigurer::disable) | ||
.oauth2ResourceServer( | ||
customize -> | ||
customize.jwt( | ||
jwt -> jwt.jwtAuthenticationConverter(converter()).jwkSetUri(jwkSetUri))); | ||
.oauth2ResourceServer(oauth2Customizer); | ||
|
||
return http.build(); | ||
} | ||
|
||
private Converter<Jwt, AbstractAuthenticationToken> converter() { | ||
JwtAuthenticationConverter converter = new JwtAuthenticationConverter(); | ||
converter.setJwtGrantedAuthoritiesConverter(roleConverter); | ||
return converter; | ||
} | ||
|
||
private final Converter<Jwt, Collection<GrantedAuthority>> roleConverter = | ||
jwt -> { | ||
if (!jwt.getClaims().containsKey("client_roles")) { | ||
return List.of(); | ||
} | ||
Object clientRolesObj = jwt.getClaims().get("client_roles"); | ||
final List<String> realmAccess = new ArrayList<>(); | ||
if (clientRolesObj instanceof List<?> list) { | ||
for (Object item : list) { | ||
realmAccess.add(String.valueOf(item)); | ||
} | ||
} | ||
return realmAccess.stream() | ||
.map(roleName -> "ROLE_" + roleName) | ||
.map(roleName -> (GrantedAuthority) new SimpleGrantedAuthority(roleName)) | ||
.toList(); | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
32 changes: 32 additions & 0 deletions
32
...d/src/main/java/ca/bc/gov/restapi/results/common/security/ApiAuthorizationCustomizer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package ca.bc.gov.restapi.results.common.security; | ||
|
||
import org.springframework.http.HttpMethod; | ||
import org.springframework.security.config.Customizer; | ||
import org.springframework.security.config.annotation.web.builders.HttpSecurity; | ||
import org.springframework.security.config.annotation.web.configurers.AuthorizeHttpRequestsConfigurer; | ||
import org.springframework.stereotype.Component; | ||
|
||
@Component | ||
public class ApiAuthorizationCustomizer implements | ||
Customizer<AuthorizeHttpRequestsConfigurer<HttpSecurity>.AuthorizationManagerRequestMatcherRegistry> { | ||
|
||
@Override | ||
public void customize( | ||
AuthorizeHttpRequestsConfigurer<HttpSecurity>.AuthorizationManagerRequestMatcherRegistry authorize) { | ||
|
||
authorize | ||
// Allow actuator endpoints to be accessed without authentication | ||
// This is useful for monitoring and health checks | ||
.requestMatchers(HttpMethod.GET, "/actuator/**") | ||
.permitAll() | ||
// Protect everything under /api with authentication | ||
.requestMatchers("/api/**") | ||
.authenticated() | ||
// Allow OPTIONS requests to be accessed with authentication | ||
.requestMatchers(HttpMethod.OPTIONS, "/**") | ||
.authenticated() | ||
// Deny all other requests | ||
.anyRequest().denyAll(); | ||
|
||
} | ||
} |
17 changes: 17 additions & 0 deletions
17
backend/src/main/java/ca/bc/gov/restapi/results/common/security/CsrfSecurityCustomizer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package ca.bc.gov.restapi.results.common.security; | ||
|
||
import org.springframework.security.config.Customizer; | ||
import org.springframework.security.config.annotation.web.builders.HttpSecurity; | ||
import org.springframework.security.config.annotation.web.configurers.CsrfConfigurer; | ||
import org.springframework.security.web.csrf.CookieCsrfTokenRepository; | ||
import org.springframework.stereotype.Component; | ||
|
||
@Component | ||
public class CsrfSecurityCustomizer implements Customizer<CsrfConfigurer<HttpSecurity>> { | ||
|
||
@Override | ||
public void customize(CsrfConfigurer<HttpSecurity> csrfSpec) { | ||
csrfSpec | ||
.csrfTokenRepository(new CookieCsrfTokenRepository()); | ||
} | ||
} |
30 changes: 30 additions & 0 deletions
30
.../src/main/java/ca/bc/gov/restapi/results/common/security/GrantedAuthoritiesConverter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package ca.bc.gov.restapi.results.common.security; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Collection; | ||
import java.util.List; | ||
import org.springframework.core.convert.converter.Converter; | ||
import org.springframework.security.core.GrantedAuthority; | ||
import org.springframework.security.core.authority.SimpleGrantedAuthority; | ||
import org.springframework.security.oauth2.jwt.Jwt; | ||
|
||
public class GrantedAuthoritiesConverter implements Converter<Jwt, Collection<GrantedAuthority>> { | ||
|
||
@Override | ||
public Collection<GrantedAuthority> convert(Jwt jwt) { | ||
final List<String> realmAccess = new ArrayList<>(); | ||
Object clientRolesObj = | ||
jwt | ||
.getClaims() | ||
.getOrDefault("client_roles",List.of()); | ||
|
||
if (clientRolesObj instanceof List<?> list) { | ||
list.forEach(item -> realmAccess.add(String.valueOf(item))); | ||
} | ||
return realmAccess | ||
.stream() | ||
.map(roleName -> "ROLE_" + roleName) | ||
.map(roleName -> (GrantedAuthority) new SimpleGrantedAuthority(roleName)) | ||
.toList(); | ||
} | ||
} |
Oops, something went wrong.