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 first SSO fixes for backend into sso #3112

Open
wants to merge 6 commits into
base: sso
Choose a base branch
from
Open
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
9 changes: 5 additions & 4 deletions docker-compose-app.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,18 @@
version: "3.1"
services:
app:
image: dzhw/metadatamanagement:latest
image: local/dzhw/metadatamanagement:latest-local-minified
environment:
- SPRING_PROFILES_ACTIVE=local,minified
- SPRING_DATA_MONGODB_HOST=mongodb
- METADATAMANAGEMENT_ELASTICSEARCH-CLIENT_URL=http://elasticsearch:9200
- METADATAMANAGEMENT_ELASTICSEARCHANGULARCLIENT_URL=http://elasticsearch:9200
- SPRING_ELASTICSEARCH_REST_URIS_0=http://elasticsearch:9200
- SPRING_MAIL_HOST=maildev
- SPRING_MAIL_PORT=25
- METADATAMANAGEMENT_DARA_ENDPOINT=${DARA_ENDPOINT}
- METADATAMANAGEMENT_DARA_USERNAME=${DARA_USERNAME}
- METADATAMANAGEMENT_DARA_PASSWORD=${DARA_PASSWORD}
- SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_ISSUER-URI=${ISSUER_URI}
- SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_ISSUERURI=${ISSUER_URI}
- METADATAMANAGEMENT_AUTHMANAGEMENT_SERVER_ENDPOINT=${USERAPI_ENDPOINT}
- METADATAMANAGEMENT_AUTHMANAGEMENT_SERVER_USERNAME=${USERAPI_USERNAME}
- METADATAMANAGEMENT_AUTHMANAGEMENT_SERVER_PASSWORD=${USERAPI_PASSWORD}
Expand All @@ -27,4 +28,4 @@ services:
- mongodb
- elasticsearch
- maildev
- identity-provider
- identity_provider
116 changes: 116 additions & 0 deletions local_install_readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# local install infos

## docker

* before first `docker-compose up`:
* `mkdir -p data/mongodb/db data/mongodb/logs data/elasticsearch/data` in order to avoid wrong permissions
* if protonmail bridge is running: change smtp port of the bridge (e.g. `1026`)
* restrict ram usage of elasticsearch (optional, but recommended)
* add `ES_JAVA_OPTS` to environment of elasticsearch container in `docker-compose.yml`
* e.g. (4 gb): `- "ES_JAVA_OPTS=-Xms4096m -Xmx4096m"`

## idp

* optional:
* `docker-compose exec identity_provider apt update`
* `docker-compose exec identity_provider apt install less vim`
* also optional: update container
* `docker pull sanduhrs/identity-provider:latest`
* `docker-compose rm identity_provider`
* `docker-compose up identity_provider`
* finish idp installation:
* use sqlite (lazy me)
* create roles: http://localhost:8082/admin/people/roles
* `ROLE_ADMIN`
* `ROLE_USER`
* `ROLE_PUBLISHER`
* `ROLE_ANONYMOUS`
* `ROLE_DATA_PROVIDER`
* `ROLE_RELEASE_MANAGER`
* `ROLE_TASK_USER`
* create users: http://localhost:8082/admin/people
* `resource_server` (for backend and frontend)
* `Administrator`
* `taskuser` (for repost task)
* `ROLE_TASK_USER`
* `publisher` (for testing as a publisher)
* `ROLE_USER`
* `ROLE_PUBLISHER`
* `dataprovider` (for testing as a data provider)
* `ROLE_USER`
* `ROLE_DATA_PROVIDER`
* `<me>` (for testing as yourself)
* `Administrator`
* `ROLE_ADMIN`
* `ROLE_USER`
* `ROLE_PUBLISHER`
* `ROLE_DATA_PROVIDER`
* `ROLE_RELEASE_MANAGER`
* create clients: http://localhost:8082/admin/config/services/consumer
* `mdm_frontend`
* client id: any you like
* user: `resource_server`
* confidential: `true`
* 3rd party: `true`
* redirect: `http://localhost:8080`
* `report_task`
* client id: any you like
* user: `taskuser`
* confidential: `true`
* 3rd party: `false`
* scopes: `ROLE_TASK_USER`
* `mdm_frontend_pkce`
* client id: any you like
* user: `resource_server`
* **DON'T SET ANY SECRET** (otherwise refresh token will not work)
* confidential: `false`
* pkce: `true`
* 3rd party: `true`
* redirect: `http://localhost:8080`
* ensure claim `welcome_dialog_deactivated` is available for openid (workaround)
* http://localhost:8082/admin/structure/claims
* disable the claim `welcome_dialog_deactivated`
* enable the claim `welcome_dialog_deactivated`
* reason: claim is not listed for openid in simple oauth config until it is enabled
* create a private claim called `preferred_username` (will be added as an access token claim)
* http://localhost:8082/admin/structure/claims
* Label: `preferred_username`
* Type: `private`
* Field name: `Name`
* create an undetermined claim called `iss` (will be added as an access token claim)
* http://localhost:8082/admin/structure/claims
* Label: `iss`
* alternatively use `Issuer` as label and edit the machine name to be `iss`
* Type: `undetermined`
* Field name: any
* claims might be missing in tokens after the drupal cache has been cleared
* just disable and enable them to fix this
* http://localhost:8082/admin/structure/claims

## mongodb

* on ubuntu based systems `mongorestore` is provided by the package `mongodb-clients`

## build and run mdm with sso

* `git checkout sso`
* environment variables:
* `JAVA_HOME=/home/<me>/.sdkman/candidates/java/15.0.2.hs-adpt`
* `RESOURCE_SERVER_ISSUER_URI="http://localhost:8082/"`
* `USER_API_ENDPOINT="http://localhost:8082"`
* `USER_API_USERNAME=resource_server` (actual username on idp)
* `USER_API_PASSWORD=123` (password chosen for user `resource_server`)
* `CLIENT_ID_LOCAL=64208774-4b2d-4703-9ea5-1de6c975ae44` (uuid of consumer/client `mdm_frontend`)
* `CLIENT_SECRET_LOCAL=456` (secret chosen for consumer/client `mdm_frontend`)
* `ISSUER_LOCAL="http://localhost:8082/"`
* build frontend:
* `CLIENT_ID_LOCAL=64208774-4b2d-4703-9ea5-1de6c975ae44 CLIENT_SECRET_LOCAL=456 ISSUER_LOCAL="http://localhost:8082/" grunt buildlocal`
* build backend:
* `JAVA_HOME=/home/jana/.sdkman/candidates/java/15.0.2.hs-adpt mvn verify`
* run backend:
* `JAVA_HOME=/home/jana/.sdkman/candidates/java/15.0.2.hs-adpt RESOURCE_SERVER_ISSUER_URI="http://localhost:8082/" USER_API_ENDPOINT="http://localhost:8082" USER_API_USERNAME=resource_server USER_API_PASSWORD=123 mvn`
* use PKCE:
* `CLIENT_ID_LOCAL=64208774-4b2d-4703-9ea5-1de6c975ae44` (uuid of consumer/client `mdm_frontend_pkce`)
* `CLIENT_SECRET_LOCAL=` (consumer/client `mdm_frontend_pkce` must not have a secret set)


50 changes: 45 additions & 5 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.7</version>
<relativePath/>
<relativePath />
</parent>

<groupId>eu.dzhw.fdz</groupId>
Expand Down Expand Up @@ -399,7 +399,7 @@
</goals>
</pluginExecutionFilter>
<action>
<ignore/>
<ignore />
</action>
</pluginExecution>
<pluginExecution>
Expand All @@ -412,7 +412,7 @@
</goals>
</pluginExecutionFilter>
<action>
<ignore/>
<ignore />
</action>
</pluginExecution>
<pluginExecution>
Expand All @@ -425,7 +425,7 @@
</goals>
</pluginExecutionFilter>
<action>
<ignore/>
<ignore />
</action>
</pluginExecution>
<pluginExecution>
Expand All @@ -438,7 +438,7 @@
</goals>
</pluginExecutionFilter>
<action>
<ignore/>
<ignore />
</action>
</pluginExecution>
</pluginExecutions>
Expand Down Expand Up @@ -811,6 +811,19 @@
</arguments>
</configuration>
</execution>
<execution>
<id>unpack-fat-jar</id>
<phase>install</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>deploy/unjar.sh</executable>
<arguments>
<argument>${project.build.finalName}.war</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
Expand Down Expand Up @@ -866,8 +879,35 @@
</arguments>
</configuration>
</execution>
<execution>
<id>unpack-fat-jar</id>
<phase>install</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>deploy/unjar.sh</executable>
<arguments>
<argument>${project.build.finalName}.war</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
<?SORTPOM IGNORE?>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<configuration>
<repository>local/dzhw/${project.artifactId}</repository>
<tag>${project.version}-${project.activeProfiles[0].id}</tag>
<registryUrl></registryUrl>
<buildArgs>
<JAR_FILE>target/${project.build.finalName}.war</JAR_FILE>
</buildArgs>
</configuration>
</plugin>
<?SORTPOM RESUME?>
</plugins>
</build>
</profile>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ public final class DrupalJwtConverter extends JwtAuthenticationConverter {
* Construct the Converter and set the {@link GrantedAuthority} Converter to a custom converter.
*/
public DrupalJwtConverter() {
// value of the claim specified by principalClaimName is used as name in the resulting
// authentication object
super.setPrincipalClaimName("preferred_username");
super.setJwtGrantedAuthoritiesConverter(new DrupalJwtGrantedAuthoritiesConverter());
}

Expand All @@ -43,11 +46,16 @@ public Collection<GrantedAuthority> convert(@NotNull Jwt jwt) {
return getAuthorities(jwt)
.stream()
.map(
authority -> new SimpleGrantedAuthority(PREFIX + authority.toUpperCase(Locale.GERMAN))
authority -> new SimpleGrantedAuthority(
this.getGrantedAuthorityPrefix(authority) + authority.toUpperCase(Locale.GERMAN))
)
.collect(Collectors.toList());
}

private String getGrantedAuthorityPrefix(final String jwtAuthority) {
return !jwtAuthority.toUpperCase(Locale.GERMAN).startsWith(PREFIX) ? PREFIX : "";
}

private List<String> getAuthorities(Jwt jwt) {
var authorities = jwt.getClaimAsStringList(CLAIM_NAME);

Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/bin/run-report-task.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/bash
# this script gives an example for running the report generation
# in the docker container connecting to localhost
docker run --network=host 347729458675.dkr.ecr.eu-central-1.amazonaws.com/dzhw/report-task:latest-dev java -jar /app/report-task.jar --task.id=$1 --task.version=$2 --task.language=$3 --task.onBehalfOf=$4 --task.type=$5 --mdm.username=${MDM_TASK_USER} --mdm.password=${MDM_TASK_PASSWORD} --mdm.endpoint=http://127.0.0.1:8080
docker run --network=host local/dzhw/report-task:latest-local java -jar /app/report-task.jar --task.id=$1 --task.version=$2 --task.language=$3 --task.onBehalfOf=$4 --task.type=$5 --mdm.username=${MDM_TASK_USER} --mdm.password=${MDM_TASK_PASSWORD} --mdm.endpoint=http://127.0.0.1:8080
11 changes: 10 additions & 1 deletion src/main/webapp/scripts/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -194,8 +194,17 @@ try {
if (code) {
Auth.authorize(code).then(function() {
init();
}, function() {
}, function(error) {
// @todo display some error message
console.log(error);
console.log($location.search());
init();
$state.go('start', {
lang: LanguageService.getCurrentInstantly(),
data: {
authenticationError: true
}
});
});
} else {
Auth.init().then(function() {
Expand Down
14 changes: 13 additions & 1 deletion src/main/webapp/scripts/usermanagement/auth/principal.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
angular.module('metadatamanagementApp').factory(
'Principal',
function Principal($q, AuthServiceProvider, $rootScope, $sessionStorage,
WelcomeDialogService, $state, LanguageService, $injector) {
WelcomeDialogService, $state, LanguageService, $injector,
$http) {

if (AuthServiceProvider.hasToken()) {
$rootScope.identity = AuthServiceProvider.idTokenInfo();
Expand All @@ -12,10 +13,20 @@ angular.module('metadatamanagementApp').factory(

//@todo: save welcome dialog state in dpl
var displayWelcomeDialog = function() {
var tokenInfo = AuthServiceProvider.idTokenInfo();
return !tokenInfo.welcome_dialog_deactivated;
/*return _identity &&
_.indexOf(identity.authorities, 'ROLE_DATA_PROVIDER') !== -1 &&
!identity.welcomeDialogDeactivated;*/
};
var deactivateWelcomeDialogIDP = function(hideDialog) {
if (hideDialog &&
!AuthServiceProvider.idTokenInfo().welcome_dialog_deactivated) {
var url =
'api/users/deactivatedWelcomeDialog?deactivatedWelcomeDialog=true';
return $http.patch(url);
}
};

return {
isUiLoggedIn: function() {
Expand Down Expand Up @@ -87,6 +98,7 @@ angular.module('metadatamanagementApp').factory(
AuthServiceProvider.idTokenInfo().preferred_username)
.then(function(hideWelcomeDialog) {
if (hideWelcomeDialog) {
deactivateWelcomeDialogIDP(hideWelcomeDialog);
//_identity.welcomeDialogDeactivated = true;
//@todo: save state in dpl user profile
}
Expand Down
Loading