Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

merge os #32

Merged
merged 5 commits into from
May 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/dockerImage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
- name: Setup JVM
uses: actions/setup-java@v1
with:
java-version: 11.0.10
java-version: 17.0.7
java-package: jdk
architecture: x64
- name: Caching maven dependencies
Expand Down Expand Up @@ -62,7 +62,7 @@ jobs:
push_to_registry:
strategy:
matrix:
registry: ["docker.pkg.github.com", "ghcr.io"]
registry: ["ghcr.io"]
needs: [test]
name: Push Docker image to GitHub Packages
runs-on: ubuntu-latest
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/feature-branch.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
- name: Setup JVM
uses: actions/setup-java@v2
with:
java-version: "11"
java-version: 17.0.7
distribution: "adopt"
architecture: x64

Expand Down
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
FROM adoptopenjdk/openjdk11
FROM openjdk:17-oracle
VOLUME ["/tmp","/log"]
EXPOSE 8080
ARG JAR_FILE
COPY ./LiveService.jar app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
ENTRYPOINT ["java","-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
53 changes: 44 additions & 9 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,25 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.14</version>
<version>3.0.6</version>
<relativePath/>
</parent>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>11</java.version>
<java.version>17</java.version>
<keycloak.version>17.0.0</keycloak.version>
<!-- force at least version 2.16 due to https://logging.apache.org/log4j/2.x/security.html -->
<log4j.version>2.17.1</log4j.version>
<log4j.version>2.19.0</log4j.version>
<jackson-databind-nullable.version>0.2.3</jackson-databind-nullable.version>
<spring-security.version>5.7.5</spring-security.version>
<openapi-generator-maven-plugin.version>5.1.1</openapi-generator-maven-plugin.version>
<spring-security.version>6.0.5</spring-security.version>
<openapi-generator-maven-plugin.version>6.6.0</openapi-generator-maven-plugin.version>
<springfox-boot-starter.version>3.0.0</springfox-boot-starter.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<ehcache.version>2.10.9.2</ehcache.version>
<hibernate.validator.version>8.0.0.Final</hibernate.validator.version>
</properties>

<dependencies>
Expand All @@ -41,17 +45,14 @@
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-messaging</artifactId>
<version>5.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>5.3.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>5.3.5.RELEASE</version>
</dependency>

<dependency>
Expand All @@ -66,6 +67,22 @@
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>

<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>${ehcache.version}</version>
<exclusions>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</exclusion>
</exclusions>
</dependency>

<dependency>
<groupId>org.codehaus.plexus</groupId>
Expand Down Expand Up @@ -105,12 +122,24 @@
<version>${jackson-databind-nullable.version}</version>
</dependency>
<!-- SpringFox: generate YAML file from POJOs and generate documentation -->
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-annotations</artifactId>
<version>2.2.15</version>
</dependency>
<!-- SpringFox: generate YAML file from POJOs and generate documentation -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>${springfox-boot-starter.version}</version>
</dependency>

<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>${hibernate.validator.version}</version>
</dependency>

<!-- Keycloak dependencies -->
<dependency>
<groupId>org.keycloak</groupId>
Expand Down Expand Up @@ -175,6 +204,11 @@
<version>2.0</version>
</dependency>

<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
</dependency>

<!-- Test dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
Expand Down Expand Up @@ -241,7 +275,7 @@
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>5.1.1</version>
<version>6.6.0</version>
<executions>
<execution>
<goals>
Expand All @@ -251,6 +285,7 @@
<configOptions>
<interfaceOnly>true</interfaceOnly>
<sourceFolder>/</sourceFolder>
<useSpringBoot3>true</useSpringBoot3>
</configOptions>
<inputSpec>${project.basedir}/api/liveservice.yaml</inputSpec>
<generatorName>spring</generatorName>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package de.caritas.cob.liveservice.api.auth;

import com.google.common.collect.Lists;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.stereotype.Service;

@Service
public class AuthorisationService {

private final RoleAuthorizationAuthorityMapper roleAuthorizationAuthorityMapper =
new RoleAuthorizationAuthorityMapper();

public Object getUsername() {
return getPrincipal().getClaims().get("username");
}

private Authentication getAuthentication() {
return SecurityContextHolder.getContext().getAuthentication();
}

private Jwt getPrincipal() {
return (Jwt) getAuthentication().getPrincipal();
}

public Collection<GrantedAuthority> extractRealmAuthorities(Jwt jwt) {
var roles = extractRealmRoles(jwt);
return roleAuthorizationAuthorityMapper.mapAuthorities(
roles.stream().collect(Collectors.toSet()));
}

public Collection<String> extractRealmRoles(Jwt jwt) {
Map<String, Object> realmAccess = (Map<String, Object>) jwt.getClaims().get("realm_access");
if (realmAccess != null) {
var roles = (List<String>) realmAccess.get("roles");
if (roles != null) {
return roles;
}
}
return Lists.newArrayList();
}
}
46 changes: 46 additions & 0 deletions src/main/java/de/caritas/cob/liveservice/api/auth/Authority.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package de.caritas.cob.liveservice.api.auth;

import com.google.common.collect.Lists;
import java.util.List;
import java.util.stream.Stream;
import lombok.Getter;

/** Definition of all authorities and of the role-authority-mapping. */
@Getter
public enum Authority {
CONSULTANT(UserRole.CONSULTANT, "AUTHORIZATION_CONSULTANT_DEFAULT"),
USER(UserRole.USER, "AUTHORIZATION_USER_DEFAULT"),

JITSI_TECHNICAL(UserRole.JITSI_TECHNICAL, "AUTHORIZATION_JITSI_TECHNICAL_DEFAULT");

private final UserRole role;
private final List<String> authorities;

Authority(final UserRole role, final String authorityName) {
this.role = role;
this.authorities = Lists.newArrayList(authorityName);
}

/**
* Finds a {@link Authority} instance by given roleName.
*
* @param roleName the role name to search for
* @return the {@link Authority} instance
*/
public static Authority fromRoleName(String roleName) {
return Stream.of(values())
.filter(authority -> authority.role.getValue().equals(roleName))
.findFirst()
.orElse(null);
}

public static class AuthorityValue {

private AuthorityValue() {}

public static final String PREFIX = "AUTHORIZATION_";
public static final String CONSULTANT = PREFIX + "CONSULTANT_DEFAULT";
public static final String USER = PREFIX + "USER_DEFAULT";
public static final String JITSI_TECHNICAL = PREFIX + "JITSI_TECHNICAL_DEFAULT";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package de.caritas.cob.liveservice.api.auth;

import de.caritas.cob.liveservice.config.security.JwtAuthConverterProperties;
import java.util.Collection;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import org.springframework.core.convert.converter.Converter;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.jwt.JwtClaimNames;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter;
import org.springframework.stereotype.Component;

@Component
@RequiredArgsConstructor
public class JwtAuthConverter implements Converter<Jwt, AbstractAuthenticationToken> {

private final @NonNull AuthorisationService authorisationService;

private final JwtGrantedAuthoritiesConverter jwtGrantedAuthoritiesConverter =
new JwtGrantedAuthoritiesConverter();

private final JwtAuthConverterProperties properties;

public JwtAuthConverter(
JwtAuthConverterProperties properties, AuthorisationService authorisationService) {
this.properties = properties;
this.authorisationService = authorisationService;
}

@Override
public AbstractAuthenticationToken convert(Jwt jwt) {
var authorities = getGrantedAuthorities(jwt);
return new JwtAuthenticationToken(jwt, authorities, getPrincipalClaimName(jwt));
}

private Collection<GrantedAuthority> getGrantedAuthorities(Jwt jwt) {
Collection<GrantedAuthority> convertedGrantedAuthorities =
jwtGrantedAuthoritiesConverter.convert(jwt);
if (convertedGrantedAuthorities != null) {
return Stream.concat(
convertedGrantedAuthorities.stream(),
authorisationService.extractRealmAuthorities(jwt).stream())
.collect(Collectors.toSet());
} else {
return authorisationService.extractRealmAuthorities(jwt);
}
}

private String getPrincipalClaimName(Jwt jwt) {
String claimName = JwtClaimNames.SUB;
if (properties.getPrincipalAttribute() != null) {
claimName = properties.getPrincipalAttribute();
}
return jwt.getClaim(claimName);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package de.caritas.cob.liveservice.api.auth;

import java.util.Collection;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
import org.springframework.stereotype.Component;

/** Own implementation of the Spring GrantedAuthoritiesMapper. */
@Component
public class RoleAuthorizationAuthorityMapper implements GrantedAuthoritiesMapper {

@Override
public Collection<? extends GrantedAuthority> mapAuthorities(
Collection<? extends GrantedAuthority> authorities) {
Set<String> roleNames =
authorities.stream()
.map(GrantedAuthority::getAuthority)
.map(String::toLowerCase)
.collect(Collectors.toSet());

return mapAuthorities(roleNames);
}

public Set<GrantedAuthority> mapAuthorities(Set<String> roleNames) {
return roleNames.stream()
.map(Authority::fromRoleName)
.filter(Objects::nonNull)
.map(Authority::getAuthorities)
.flatMap(Collection::parallelStream)
.map(SimpleGrantedAuthority::new)
.collect(Collectors.toSet());
}
}
14 changes: 14 additions & 0 deletions src/main/java/de/caritas/cob/liveservice/api/auth/UserRole.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package de.caritas.cob.liveservice.api.auth;

import lombok.AllArgsConstructor;
import lombok.Getter;

@AllArgsConstructor
@Getter
public enum UserRole {
USER("user"),
CONSULTANT("consultant"),
JITSI_TECHNICAL("jitsi-technical");

private final String value;
}

This file was deleted.

Loading
Loading