-
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.
Merge pull request #19 from nla/develop/FOLIOINT-370
Develop/folioint 370
- Loading branch information
Showing
17 changed files
with
724 additions
and
82 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
HELP.md | ||
target/ | ||
!.mvn/wrapper/maven-wrapper.jar | ||
!**/src/main/**/target/ | ||
!**/src/test/**/target/ | ||
|
||
### STS ### | ||
.apt_generated | ||
.classpath | ||
.factorypath | ||
.project | ||
.settings | ||
.springBeans | ||
.sts4-cache | ||
|
||
### IntelliJ IDEA ### | ||
.idea | ||
*.iws | ||
*.iml | ||
*.ipr | ||
|
||
### NetBeans ### | ||
/nbproject/private/ | ||
/nbbuild/ | ||
/dist/ | ||
/nbdist/ | ||
/.nb-gradle/ | ||
build/ | ||
!**/src/main/**/build/ | ||
!**/src/test/**/build/ | ||
|
||
### VS Code ### | ||
.vscode/ | ||
|
||
## props (with passwords) | ||
|
||
src/main/resources/static/application.properties | ||
application-local.properties | ||
/releases/ | ||
run.sh | ||
deployAndRunVoyagerLoader.sh | ||
justRunAlreadyDeployedVoyagerLoader.sh |
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
45 changes: 45 additions & 0 deletions
45
src/main/java/au/gov/nla/pickslip/config/KeycloakJwtAuthenticationConverter.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,45 @@ | ||
package au.gov.nla.pickslip.config; | ||
|
||
import lombok.AllArgsConstructor; | ||
import lombok.NonNull; | ||
import org.springframework.core.convert.converter.Converter; | ||
import org.springframework.security.authentication.AbstractAuthenticationToken; | ||
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.JwtAuthenticationToken; | ||
import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter; | ||
import org.springframework.stereotype.Component; | ||
|
||
import java.util.Collection; | ||
import java.util.Collections; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.stream.Stream; | ||
|
||
import static java.util.stream.Collectors.toSet; | ||
|
||
@AllArgsConstructor | ||
@Component | ||
public class KeycloakJwtAuthenticationConverter implements Converter<Jwt, | ||
AbstractAuthenticationToken> { | ||
|
||
@Override | ||
public AbstractAuthenticationToken convert(@NonNull Jwt source) { | ||
return new JwtAuthenticationToken(source, | ||
Stream.concat(new JwtGrantedAuthoritiesConverter().convert(source) | ||
.stream(), extractResourceRoles(source).stream()) | ||
.collect(toSet())); | ||
} | ||
|
||
private Collection<? extends GrantedAuthority> extractResourceRoles(Jwt jwt) { | ||
if (jwt.hasClaim("realm_access")) { | ||
List<String> roleList = | ||
new HashMap<String, List<String>>(jwt.getClaim("realm_access")).get("roles"); | ||
return roleList.isEmpty() ? Collections.emptySet() : roleList.stream() | ||
.map(role -> new SimpleGrantedAuthority("ROLE_" + role.toUpperCase())) | ||
.collect(toSet()); | ||
} | ||
return Collections.emptySet(); | ||
} | ||
} |
46 changes: 46 additions & 0 deletions
46
src/main/java/au/gov/nla/pickslip/config/KeycloakLogoutHandler.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,46 @@ | ||
package au.gov.nla.pickslip.config; | ||
|
||
import jakarta.servlet.http.HttpServletRequest; | ||
import jakarta.servlet.http.HttpServletResponse; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.security.core.Authentication; | ||
import org.springframework.security.oauth2.core.oidc.user.OidcUser; | ||
import org.springframework.security.web.authentication.logout.LogoutHandler; | ||
import org.springframework.stereotype.Component; | ||
import org.springframework.web.client.RestClient; | ||
import org.springframework.web.util.UriComponentsBuilder; | ||
|
||
@Component | ||
@Slf4j | ||
public class KeycloakLogoutHandler implements LogoutHandler { | ||
|
||
private final RestClient restClient = RestClient.create(); | ||
|
||
@Override | ||
public void logout( | ||
HttpServletRequest request, HttpServletResponse response, Authentication auth) { | ||
logoutFromKeycloak((OidcUser) auth.getPrincipal()); | ||
} | ||
|
||
private void logoutFromKeycloak(OidcUser user) { | ||
String endSessionEndpoint = user.getIssuer() + "/protocol/openid-connect/logout"; | ||
UriComponentsBuilder builder = | ||
UriComponentsBuilder.fromUriString(endSessionEndpoint) | ||
.queryParam("id_token_hint", user.getIdToken() | ||
.getTokenValue()); | ||
|
||
ResponseEntity<String> result = restClient.get() | ||
.uri(builder.toUriString()) | ||
.retrieve() | ||
.toEntity(String.class); | ||
|
||
if (result.getStatusCode() | ||
.is2xxSuccessful()) { | ||
log.info("Keycloak logout successful: {}", user.getPreferredUsername()); | ||
} | ||
else { | ||
log.warn("Keycloak logout unsuccessful: {}", result.getBody()); | ||
} | ||
} | ||
} |
46 changes: 46 additions & 0 deletions
46
src/main/java/au/gov/nla/pickslip/config/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 |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package au.gov.nla.pickslip.config; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
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.web.SecurityFilterChain; | ||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher; | ||
|
||
import java.util.Arrays; | ||
|
||
@Configuration | ||
@EnableWebSecurity | ||
@EnableMethodSecurity( | ||
securedEnabled = true, | ||
jsr250Enabled = true) | ||
@Slf4j | ||
@RequiredArgsConstructor | ||
public class SecurityConfiguration { | ||
static String[] ANONYMOUS_PATHS = {"/export/**", "/bulkprint/**", "/location/**", "/", "/home", | ||
"/user/**", "/webjars/**", "/css/**"}; | ||
|
||
private final KeycloakLogoutHandler keycloakLogoutHandler; | ||
|
||
|
||
@Bean | ||
public SecurityFilterChain filterChain(final HttpSecurity http) throws Exception { | ||
http.authorizeHttpRequests( | ||
authorizeHttpRequests -> | ||
authorizeHttpRequests | ||
.requestMatchers(Arrays.stream(ANONYMOUS_PATHS) | ||
.map(AntPathRequestMatcher::antMatcher) | ||
.toArray(AntPathRequestMatcher[]::new)) | ||
.permitAll() | ||
.anyRequest() | ||
.authenticated()) | ||
.oauth2Login(Customizer.withDefaults()) | ||
.logout(logout -> logout.addLogoutHandler(keycloakLogoutHandler) | ||
.logoutSuccessUrl("/")); | ||
return http.build(); | ||
} | ||
} |
Oops, something went wrong.