Skip to content

Commit

Permalink
Merge pull request #32 from Onlineberatung/develop
Browse files Browse the repository at this point in the history
merge os
  • Loading branch information
tkuzynow authored May 29, 2024
2 parents b52c722 + 030fb81 commit 0edacf6
Show file tree
Hide file tree
Showing 15 changed files with 311 additions and 62 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/dockerImage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,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

Expand Down Expand Up @@ -65,7 +65,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

0 comments on commit 0edacf6

Please sign in to comment.