diff --git a/subato-web/package.json b/subato-web/package.json
index 285c8338ccfa09e988b1cc53adb82ddf48675aa3..9e4f62287d9464092dcf28de0dbeb79dc2fb8d2a 100755
--- a/subato-web/package.json
+++ b/subato-web/package.json
@@ -1,6 +1,6 @@
 {
     "name": "subato-web",
-    "version": "2.1.0",
+    "version": "2.1.1",
     "license": "MIT",
     "scripts": {
         "ng": "ng",
diff --git a/subato-web/src/app/exercises/pages/submit-solution/components/intellij-import/intellij-import.component.ts b/subato-web/src/app/exercises/pages/submit-solution/components/intellij-import/intellij-import.component.ts
index 0217d6917a6b3fad9c221930926a6776a1d0dd82..3463962a4f946c20024fccbc5b90274749ab58a1 100644
--- a/subato-web/src/app/exercises/pages/submit-solution/components/intellij-import/intellij-import.component.ts
+++ b/subato-web/src/app/exercises/pages/submit-solution/components/intellij-import/intellij-import.component.ts
@@ -24,8 +24,7 @@ export class IntellijImportComponent implements OnInit {
     }
 
     generateImportUrl() {
-        let rootUrl =
-            window.location.protocol + '//' + window.location.host + '/';
+        let rootUrl = window.location.protocol + '//' + window.location.host;
         this.importUrl = `${rootUrl}/exercises/${this.taskInstance.exercise.id}/tasks/${this.taskInstance.task.id}`;
     }
 
diff --git a/subato-web/src/app/misconceptions/models/concept.ts b/subato-web/src/app/misconceptions/models/concept.ts
index f8b2b41a942c2b9a28cc82a246ff7b953fcf1d6a..79a027b6f145663372a659a6271c58b49b8d7bea 100644
--- a/subato-web/src/app/misconceptions/models/concept.ts
+++ b/subato-web/src/app/misconceptions/models/concept.ts
@@ -1,5 +1,5 @@
 export class Concept {
-    id: number;
+    id: string;
     name: string;
 
     constructor(dto: any) {
diff --git a/subato-web/src/app/profile/profile-store.ts b/subato-web/src/app/profile/profile-store.ts
index 9536a1f08232367e88237f1ef2492ece04004068..af3c167589ffa81ce40ff12f63d0aa56906e9a8a 100644
--- a/subato-web/src/app/profile/profile-store.ts
+++ b/subato-web/src/app/profile/profile-store.ts
@@ -82,9 +82,13 @@ export class ProfileStore extends ComponentStore<ProfileState> {
                             this.globalErrorHandler.handleError(err)
                         ),
                         catchError((error) => {
+                            this.patchState({
+                                saving: false,
+                                loading: false,
+                            });
+
                             if (isValidationError(error)) {
                                 this.patchState({
-                                    saving: false,
                                     validationError: error,
                                 });
                             }
diff --git a/subato-web/src/app/tasks/models/task.ts b/subato-web/src/app/tasks/models/task.ts
index e57623d4a0518467641bfdfb952a78cd3e6289cc..c256b346c8deb9cd16cfd428eecdaf8d1491e2d3 100755
--- a/subato-web/src/app/tasks/models/task.ts
+++ b/subato-web/src/app/tasks/models/task.ts
@@ -3,6 +3,7 @@ import { SubmissionMode } from './submission-mode';
 import { TaskFeedbackStats } from './task-feedback-stats';
 import { TaskPool } from './task-pool';
 import { Evaluator } from './evaluator';
+import { Concept } from 'app/misconceptions/models/concept';
 
 export class Task {
     id: number;
@@ -20,6 +21,7 @@ export class Task {
     feedbackStats: TaskFeedbackStats;
     acceptanceTestAvailable: boolean;
     evaluator: Evaluator;
+    concepts: Concept[];
     repositoryUrl: string;
     archived: boolean;
     allowedExtensions: string[];
@@ -43,5 +45,8 @@ export class Task {
         this.repositoryUrl = task.repositoryUrl;
         this.allowedExtensions = task.allowedExtensions;
         this.archived = task.archived;
+        this.concepts = task.concepts
+            ? task.concepts.map((c) => new Concept(c))
+            : [];
     }
 }
diff --git a/subato-web/src/app/tasks/pages/task/components/concepts/concepts.component.html b/subato-web/src/app/tasks/pages/task/components/concepts/concepts.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..18af3478288208fca0992951dbf60980e720ecc0
--- /dev/null
+++ b/subato-web/src/app/tasks/pages/task/components/concepts/concepts.component.html
@@ -0,0 +1,13 @@
+<nb-card>
+    <nb-card-header>Konzepte</nb-card-header>
+    <nb-card-body>
+        <nb-tag-list *ngIf="concepts.length != 0">
+            <nb-tag *ngFor="let concept of concepts" class="no-hover"
+                    appearance="filled" [status]="'basic'"
+                    [text]="concept.name">
+            </nb-tag>
+        </nb-tag-list>
+
+        <span *ngIf="concepts.length == 0">Keine vorhanden.</span>
+    </nb-card-body>
+</nb-card>
diff --git a/subato-web/src/app/tasks/pages/task/components/concepts/concepts.component.scss b/subato-web/src/app/tasks/pages/task/components/concepts/concepts.component.scss
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/subato-web/src/app/tasks/pages/task/components/concepts/concepts.component.ts b/subato-web/src/app/tasks/pages/task/components/concepts/concepts.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..94fde0375471280999970a81386112cc53c7c97e
--- /dev/null
+++ b/subato-web/src/app/tasks/pages/task/components/concepts/concepts.component.ts
@@ -0,0 +1,15 @@
+import { Component, Input, OnInit } from '@angular/core';
+import { Concept } from 'app/misconceptions/models/concept';
+
+@Component({
+    selector: 'sb-task-concepts',
+    templateUrl: './concepts.component.html',
+    styleUrls: ['./concepts.component.scss'],
+})
+export class ConceptsComponent implements OnInit {
+    @Input() concepts: Concept[];
+
+    constructor() {}
+
+    ngOnInit(): void {}
+}
diff --git a/subato-web/src/app/tasks/pages/task/task.page.component.html b/subato-web/src/app/tasks/pages/task/task.page.component.html
index d0fa40f75f07ba73cdb8e71fea9a28ee4ceceacf..18948ab53b9d10373c238efe6d435e7d9b6d0882 100644
--- a/subato-web/src/app/tasks/pages/task/task.page.component.html
+++ b/subato-web/src/app/tasks/pages/task/task.page.component.html
@@ -51,6 +51,14 @@
                         </div>
                     </div>
 
+                    <div class="row">
+                        <div class="col-12">
+                            <sb-task-concepts
+                                [concepts]="vm.taskState.task.concepts">
+                            </sb-task-concepts>
+                        </div>
+                    </div>
+
                     <div class="row">
                         <div class="col-12">
                             <nb-card>
diff --git a/subato-web/src/app/tasks/pages/task/task.page.module.ts b/subato-web/src/app/tasks/pages/task/task.page.module.ts
index 5b98bcdabc03c5cb0fa4a643240a4a808a96dd5b..1ed936189683b3cd5463ffe2f25637ad09659f0a 100644
--- a/subato-web/src/app/tasks/pages/task/task.page.module.ts
+++ b/subato-web/src/app/tasks/pages/task/task.page.module.ts
@@ -10,6 +10,7 @@ import { TaskPageComponent } from 'app/tasks/pages/task/task.page.component';
 import { FeedbackInfoComponent } from 'app/tasks/pages/task/components/feedback-info/feedback-info.component';
 import { SolutionsSharedModule } from 'app/solutions/shared/solutions-shared.module';
 import { TaskCardComponent } from 'app/tasks/pages/task/components/task-card/task-card.component';
+import { ConceptsComponent } from './components/concepts/concepts.component';
 
 @NgModule({
     declarations: [
@@ -19,6 +20,7 @@ import { TaskCardComponent } from 'app/tasks/pages/task/components/task-card/tas
         TaskCardComponent,
         RepoHintComponent,
         FeedbackInfoComponent,
+        ConceptsComponent,
     ],
     imports: [
         CommonModule,
diff --git a/subato-web/src/environments/shared.ts b/subato-web/src/environments/shared.ts
index db6450e3ff5d8f9cfb0dd29fd099c31ed9979b0b..59ee39b2cbf8ee0e39273079e9fdfa28941c952c 100644
--- a/subato-web/src/environments/shared.ts
+++ b/subato-web/src/environments/shared.ts
@@ -2,7 +2,7 @@ let docsUrl = 'http://docs.subato-test2.local.cs.hs-rm.de';
 let manualUrl = `${docsUrl}/docs`;
 
 export const shared = {
-    version: '2.1.0',
+    version: '2.1.1',
     docsUrl: docsUrl,
     manualUrl: manualUrl,
     stefDocsUrl: `${docsUrl}/stef`,
diff --git a/subato/build.gradle b/subato/build.gradle
index 11a4938e487642fa7bc715689d7f3459d8e8b8ad..e8d66ec2be0fdba7c5dbd471927a9d66be371c08 100755
--- a/subato/build.gradle
+++ b/subato/build.gradle
@@ -19,7 +19,7 @@ plugins {
 }
 
 group = 'de.hsrm.sls'
-version = '2.1.0-SNAPSHOT'
+version = '2.1.1-SNAPSHOT'
 
 repositories {
     mavenCentral()
diff --git a/subato/src/main/java/de/hsrm/sls/subato/shared/config/SubatoConfig.java b/subato/src/main/java/de/hsrm/sls/subato/shared/config/SubatoConfig.java
index 7b8da6a2f0045d90c64c032cc114518d06c34f64..831dd0093ea6aaf17acf68560e0460d6cb014c8b 100644
--- a/subato/src/main/java/de/hsrm/sls/subato/shared/config/SubatoConfig.java
+++ b/subato/src/main/java/de/hsrm/sls/subato/shared/config/SubatoConfig.java
@@ -12,6 +12,7 @@ public class SubatoConfig {
     private String seedDir;
     private String publicHostname;
     private int maxLabChanges;
+    private Integer maxConsentChanges;
 
     public String getTmpDir() {
         return tmpDir;
@@ -52,4 +53,12 @@ public class SubatoConfig {
     public void setMaxLabChanges(int maxLabChanges) {
         this.maxLabChanges = maxLabChanges;
     }
+
+    public Integer getMaxConsentChanges() {
+        return maxConsentChanges;
+    }
+
+    public void setMaxConsentChanges(Integer maxConsentChanges) {
+        this.maxConsentChanges = maxConsentChanges;
+    }
 }
diff --git a/subato/src/main/java/de/hsrm/sls/subato/shared/error/rendering/HtmlExceptionRenderer.java b/subato/src/main/java/de/hsrm/sls/subato/shared/error/rendering/HtmlExceptionRenderer.java
index f6d2b1738d4f234c811bfc801ce09058200a53b9..8a521862c4c824ea40af5fd5dd61cba21bc2568b 100644
--- a/subato/src/main/java/de/hsrm/sls/subato/shared/error/rendering/HtmlExceptionRenderer.java
+++ b/subato/src/main/java/de/hsrm/sls/subato/shared/error/rendering/HtmlExceptionRenderer.java
@@ -20,7 +20,7 @@ public class HtmlExceptionRenderer implements ExceptionRenderer {
 
     private final RequestCache requestCache = new HttpSessionRequestCache();
 
-    @Value("${spring.profiles.active")
+    @Value("${spring.profiles.active:}")
     private String activeProfile;
 
     @Override
diff --git a/subato/src/main/java/de/hsrm/sls/subato/shared/swagger/SwaggerConfiguration.java b/subato/src/main/java/de/hsrm/sls/subato/shared/swagger/SwaggerConfiguration.java
index ebc07762162fe6d38d202eb9e761f88903ecd886..7acb764058d90ca064bc537b6e63edf1db849ec2 100644
--- a/subato/src/main/java/de/hsrm/sls/subato/shared/swagger/SwaggerConfiguration.java
+++ b/subato/src/main/java/de/hsrm/sls/subato/shared/swagger/SwaggerConfiguration.java
@@ -30,7 +30,7 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
 @Configuration
 public class SwaggerConfiguration implements WebMvcConfigurer {
 
-    private final String API_VERSION = "2.1.0";
+    private final String API_VERSION = "2.1.1";
 
     @Value("${keycloak.auth-server-url}")
     private String keycloakUrl;
diff --git a/subato/src/main/java/de/hsrm/sls/subato/tasks/stef/cache/StefSpecCache.java b/subato/src/main/java/de/hsrm/sls/subato/tasks/stef/cache/StefSpecCache.java
index 7fb66a098c8ab175568d4642c3bbcbb131f87039..fdd4045adbe14226194f770cf4462ac664fa7584 100644
--- a/subato/src/main/java/de/hsrm/sls/subato/tasks/stef/cache/StefSpecCache.java
+++ b/subato/src/main/java/de/hsrm/sls/subato/tasks/stef/cache/StefSpecCache.java
@@ -12,7 +12,7 @@ public class StefSpecCache {
      * this value needs to be incremented if breaking changes are made in this class, which would
      * lead to parsing errors. in this case, the spec needs to be parsed and serialized again
      */
-    public static final int SERIALIZATION_VERSION = 9;
+    public static final int SERIALIZATION_VERSION = 10;
 
     /**
      * not to be confused with the version of the spec! Changes in this model can occur, even if the
diff --git a/subato/src/main/java/de/hsrm/sls/subato/tasks/stef/parser/meta/ConceptResolver.java b/subato/src/main/java/de/hsrm/sls/subato/tasks/stef/parser/meta/ConceptResolver.java
new file mode 100644
index 0000000000000000000000000000000000000000..dc07796389a5628280dae2a926cc94caa4b5ee3b
--- /dev/null
+++ b/subato/src/main/java/de/hsrm/sls/subato/tasks/stef/parser/meta/ConceptResolver.java
@@ -0,0 +1,45 @@
+package de.hsrm.sls.subato.tasks.stef.parser.meta;
+
+import de.hsrm.sls.subato.misclib.MisconceptionRepository;
+import de.hsrm.sls.subato.misclib.model.Concept;
+import de.hsrm.sls.subato.tasks.stef.parser.meta.xml.TaskXml;
+import java.util.ArrayList;
+import java.util.List;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+class ConceptResolver {
+
+    private static Logger logger = LoggerFactory.getLogger(ConceptResolver.class);
+
+    @Autowired
+    private MisconceptionRepository misconceptionRepository;
+
+    public List<Concept> resolve(TaskXml doc) {
+        var concepts = new ArrayList<Concept>();
+
+        if (doc.getConcepts() == null) {
+            return concepts;
+        }
+
+        var availableConcepts = misconceptionRepository.getConcepts();
+        for (var conceptXml : doc.getConcepts().getConcepts()) {
+            var matchingConcept = availableConcepts.stream()
+                .filter(c -> c.getId().equals(conceptXml.getId())).findFirst().orElse(null);
+            if (matchingConcept == null) {
+                continue;
+                /*
+                throw new InvalidSpecException(
+                    "Konzept %s existiert nicht im System".formatted(conceptXml.getId()));
+                 */
+            }
+
+            concepts.add(matchingConcept);
+        }
+
+        return concepts;
+    }
+}
diff --git a/subato/src/main/java/de/hsrm/sls/subato/tasks/stef/parser/meta/MetaParser.java b/subato/src/main/java/de/hsrm/sls/subato/tasks/stef/parser/meta/MetaParser.java
index 06184009f9c60572a54ac2c8172e02e0515e2f28..351403d01f0961a2d3fcb870ccbd7ed1c97374eb 100644
--- a/subato/src/main/java/de/hsrm/sls/subato/tasks/stef/parser/meta/MetaParser.java
+++ b/subato/src/main/java/de/hsrm/sls/subato/tasks/stef/parser/meta/MetaParser.java
@@ -36,6 +36,9 @@ public class MetaParser {
     @Autowired
     private MimeMappingResolver mimeMappingResolver;
 
+    @Autowired
+    private ConceptResolver conceptResolver;
+
     @Autowired
     private StefConfig stefConfig;
 
@@ -65,6 +68,9 @@ public class MetaParser {
         var submissionModeConfig = submissionModeResolver.resolve(doc, meta.getTemplateFiles());
         meta.setSubmissionModeConfig(submissionModeConfig);
 
+        var concepts = conceptResolver.resolve(doc);
+        meta.setConcepts(concepts);
+
         return meta;
     }
 
diff --git a/subato/src/main/java/de/hsrm/sls/subato/tasks/stef/parser/meta/xml/ConceptXml.java b/subato/src/main/java/de/hsrm/sls/subato/tasks/stef/parser/meta/xml/ConceptXml.java
new file mode 100644
index 0000000000000000000000000000000000000000..1b3beef62a5439cd44f4d83d5d4f92108c5d6e4c
--- /dev/null
+++ b/subato/src/main/java/de/hsrm/sls/subato/tasks/stef/parser/meta/xml/ConceptXml.java
@@ -0,0 +1,17 @@
+package de.hsrm.sls.subato.tasks.stef.parser.meta.xml;
+
+import jakarta.xml.bind.annotation.XmlValue;
+
+public class ConceptXml {
+
+    private String id;
+
+    public String getId() {
+        return id;
+    }
+
+    @XmlValue
+    public void setId(String as) {
+        this.id = as;
+    }
+}
diff --git a/subato/src/main/java/de/hsrm/sls/subato/tasks/stef/parser/meta/xml/ConceptsXml.java b/subato/src/main/java/de/hsrm/sls/subato/tasks/stef/parser/meta/xml/ConceptsXml.java
new file mode 100644
index 0000000000000000000000000000000000000000..acdb116eccf0da4f47723ca3ba15460cf3007e6c
--- /dev/null
+++ b/subato/src/main/java/de/hsrm/sls/subato/tasks/stef/parser/meta/xml/ConceptsXml.java
@@ -0,0 +1,20 @@
+package de.hsrm.sls.subato.tasks.stef.parser.meta.xml;
+
+import jakarta.xml.bind.annotation.XmlElement;
+import java.util.List;
+
+public class ConceptsXml {
+
+    public static final String CONCEPT = "concept";
+
+    private List<ConceptXml> concepts;
+
+    public List<ConceptXml> getConcepts() {
+        return concepts;
+    }
+
+    @XmlElement(name = CONCEPT)
+    public void setConcepts(List<ConceptXml> concepts) {
+        this.concepts = concepts;
+    }
+}
diff --git a/subato/src/main/java/de/hsrm/sls/subato/tasks/stef/parser/meta/xml/TaskXml.java b/subato/src/main/java/de/hsrm/sls/subato/tasks/stef/parser/meta/xml/TaskXml.java
index d13de0d69b51a0aaeec0be7cfbe4fffb2684c083..07d77c200298c7d2e3696d098f72f9ca9b0df540 100644
--- a/subato/src/main/java/de/hsrm/sls/subato/tasks/stef/parser/meta/xml/TaskXml.java
+++ b/subato/src/main/java/de/hsrm/sls/subato/tasks/stef/parser/meta/xml/TaskXml.java
@@ -17,6 +17,7 @@ public class TaskXml {
     public static final String SUBMISSION_MODES = "submissionModes";
     public static final String FILES = "files";
     public static final String MIME_MAPPINGS = "mimeMappings";
+    public static final String CONCEPTS = "concepts";
 
     private Long subatoId;
     private Integer attempts;
@@ -28,6 +29,7 @@ public class TaskXml {
     private FilesXml files;
     private MimeMappingsXml mimeMappings;
     private SubmissionModesXml submissionModes;
+    private ConceptsXml concepts;
 
     public String getId() {
         return id;
@@ -118,4 +120,13 @@ public class TaskXml {
     public void setMimeMappings(MimeMappingsXml mimeMappings) {
         this.mimeMappings = mimeMappings;
     }
+
+    public ConceptsXml getConcepts() {
+        return concepts;
+    }
+
+    @XmlElement(name = CONCEPTS)
+    public void setConcepts(ConceptsXml concepts) {
+        this.concepts = concepts;
+    }
 }
diff --git a/subato/src/main/java/de/hsrm/sls/subato/tasks/stef/spec/Meta.java b/subato/src/main/java/de/hsrm/sls/subato/tasks/stef/spec/Meta.java
index d2764f1088fd8fc4e698979e5377fb12bf1c4926..d49207a89000c6511690c9b0e890ad5e1059e3fe 100644
--- a/subato/src/main/java/de/hsrm/sls/subato/tasks/stef/spec/Meta.java
+++ b/subato/src/main/java/de/hsrm/sls/subato/tasks/stef/spec/Meta.java
@@ -1,6 +1,7 @@
 package de.hsrm.sls.subato.tasks.stef.spec;
 
 import com.fasterxml.jackson.annotation.JsonIgnore;
+import de.hsrm.sls.subato.misclib.model.Concept;
 import de.hsrm.sls.subato.shared.mime.MimeMapping;
 import java.util.List;
 import java.util.stream.Collectors;
@@ -20,6 +21,7 @@ public class Meta {
     SubmissionModeConfig submissionModeConfig;
     List<FileRef> files;
     List<MimeMapping> mimeMappings;
+    List<Concept> concepts;
 
     public String getId() {
         return id;
@@ -106,4 +108,12 @@ public class Meta {
     public void setMimeMappings(List<MimeMapping> mimeMappings) {
         this.mimeMappings = mimeMappings;
     }
+
+    public List<Concept> getConcepts() {
+        return concepts;
+    }
+
+    public void setConcepts(List<Concept> concepts) {
+        this.concepts = concepts;
+    }
 }
diff --git a/subato/src/main/java/de/hsrm/sls/subato/tasks/task/dto/TaskDto.java b/subato/src/main/java/de/hsrm/sls/subato/tasks/task/dto/TaskDto.java
index 299dc1ed93870c98be2d86c805bb7893436fa864..3843cdfa123f1f2596fd2045223076cb88806adc 100644
--- a/subato/src/main/java/de/hsrm/sls/subato/tasks/task/dto/TaskDto.java
+++ b/subato/src/main/java/de/hsrm/sls/subato/tasks/task/dto/TaskDto.java
@@ -1,5 +1,6 @@
 package de.hsrm.sls.subato.tasks.task.dto;
 
+import de.hsrm.sls.subato.misclib.model.Concept;
 import de.hsrm.sls.subato.solutions.evaluation.evaluator.EvaluatorDto;
 import de.hsrm.sls.subato.tasks.feedback.model.TaskFeedbackStats;
 import de.hsrm.sls.subato.tasks.lang.dto.LanguageDto;
@@ -28,6 +29,7 @@ public class TaskDto {
     private List<String> allowedExtensions;
     private boolean archived;
     private String bundle;
+    private List<Concept> concepts;
 
     public long getId() {
         return id;
@@ -172,4 +174,12 @@ public class TaskDto {
     public void setBundle(String bundle) {
         this.bundle = bundle;
     }
+
+    public List<Concept> getConcepts() {
+        return concepts;
+    }
+
+    public void setConcepts(List<Concept> concepts) {
+        this.concepts = concepts;
+    }
 }
diff --git a/subato/src/main/java/de/hsrm/sls/subato/tasks/task/dto/TaskMapper.java b/subato/src/main/java/de/hsrm/sls/subato/tasks/task/dto/TaskMapper.java
index ebd973c84f7f9f42911d7158a4758a4fbca3b0f4..247c4efdf01388f85cb8c3f1d0d135b7337d8bd5 100644
--- a/subato/src/main/java/de/hsrm/sls/subato/tasks/task/dto/TaskMapper.java
+++ b/subato/src/main/java/de/hsrm/sls/subato/tasks/task/dto/TaskMapper.java
@@ -9,5 +9,6 @@ public interface TaskMapper {
 
     @Mapping(target = "attempts", source = "specCache.spec.meta.attempts")
     @Mapping(target = "description", source = "specCache.spec.meta.description")
+    @Mapping(target = "concepts", source = "specCache.spec.meta.concepts")
     TaskDto map(Task task);
 }
diff --git a/subato/src/main/java/de/hsrm/sls/subato/user/ConsentChangedTooOftenException.java b/subato/src/main/java/de/hsrm/sls/subato/user/ConsentChangedTooOftenException.java
new file mode 100644
index 0000000000000000000000000000000000000000..18b5328c147669f05437dc0af2acf2fcda66ff23
--- /dev/null
+++ b/subato/src/main/java/de/hsrm/sls/subato/user/ConsentChangedTooOftenException.java
@@ -0,0 +1,9 @@
+package de.hsrm.sls.subato.user;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+@ResponseStatus(code = HttpStatus.BAD_REQUEST, reason = "Du hast zu oft deine Meinung geändert. Bitte melde dich persönlich bei uns, wenn du deine Entscheidung ändern möchtest.")
+public class ConsentChangedTooOftenException extends RuntimeException {
+
+}
\ No newline at end of file
diff --git a/subato/src/main/java/de/hsrm/sls/subato/user/UpdateProfileUseCase.java b/subato/src/main/java/de/hsrm/sls/subato/user/UpdateProfileUseCase.java
index 1b9eb77856fba2678dfdcc1597125b7628574135..0d7480d204c262883a263e3ae6e5131b579c9b1a 100644
--- a/subato/src/main/java/de/hsrm/sls/subato/user/UpdateProfileUseCase.java
+++ b/subato/src/main/java/de/hsrm/sls/subato/user/UpdateProfileUseCase.java
@@ -1,6 +1,7 @@
 package de.hsrm.sls.subato.user;
 
 import de.hsrm.sls.subato.auth.principal.PrincipalService;
+import de.hsrm.sls.subato.shared.config.SubatoConfig;
 import de.hsrm.sls.subato.user.dto.UpdateProfileDto;
 import de.hsrm.sls.subato.user.repository.UserRepository;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -13,10 +14,20 @@ public class UpdateProfileUseCase {
     private UserRepository userRepository;
 
     @Autowired
-    PrincipalService principalService;
+    private PrincipalService principalService;
+
+    @Autowired
+    private SubatoConfig subatoConfig;
 
     public User update(User user, UpdateProfileDto dto) {
+        if (subatoConfig.getMaxConsentChanges() != null
+            && user.getConsentChangeCount() > subatoConfig.getMaxConsentChanges()) {
+            throw new ConsentChangedTooOftenException();
+        }
+
         user.setConsentedToCollection(dto.isConsentedToCollection());
+        user.setConsentChangeCount(user.getConsentChangeCount() + 1);
+
         user = userRepository.save(user);
         principalService.evictPrincipal(user);
         return user;
diff --git a/subato/src/main/java/de/hsrm/sls/subato/user/User.java b/subato/src/main/java/de/hsrm/sls/subato/user/User.java
index 04fd0420fdffe66b3c5e2e7502fe729bac2d447e..047ae1e552ae51ce24e26c630f5f7151bc33a747 100755
--- a/subato/src/main/java/de/hsrm/sls/subato/user/User.java
+++ b/subato/src/main/java/de/hsrm/sls/subato/user/User.java
@@ -87,6 +87,7 @@ public class User {
     private List<CourseParticipantProfile> participantProfiles = new ArrayList<>();
 
     private boolean consentedToCollection;
+    private int consentChangeCount;
 
     public User() {
     }
@@ -235,9 +236,16 @@ public class User {
         return consentedToCollection;
     }
 
-    public User setConsentedToCollection(boolean consentedToCollection) {
+    public void setConsentedToCollection(boolean consentedToCollection) {
         this.consentedToCollection = consentedToCollection;
-        return this;
+    }
+
+    public int getConsentChangeCount() {
+        return consentChangeCount;
+    }
+
+    public void setConsentChangeCount(int consentChangeCount) {
+        this.consentChangeCount = consentChangeCount;
     }
 
     @Override
diff --git a/subato/src/main/resources/application-prod.properties b/subato/src/main/resources/application-prod.properties
index 10d587c5042328a0c8ae983ca45d1454ea673679..3f1134e479e12b01e3e58f6d8406cebb404d5ff2 100644
--- a/subato/src/main/resources/application-prod.properties
+++ b/subato/src/main/resources/application-prod.properties
@@ -1,4 +1,5 @@
 server.port=8443
+subato.max_consent_changes=10
 logging.level.de.hsrm.sls.subato.=INFO
 server.ssl.enabled=true
 server.ssl.key-store-type=PKCS12
diff --git a/subato/src/main/resources/db/changelog/2023/09/22-01-changelog.yaml b/subato/src/main/resources/db/changelog/2023/09/22-01-changelog.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..ee2b430c7327cf08405d2cddae13c7907b4efd1c
--- /dev/null
+++ b/subato/src/main/resources/db/changelog/2023/09/22-01-changelog.yaml
@@ -0,0 +1,22 @@
+databaseChangeLog:
+  - changeSet:
+      id: 1695403516677-1
+      author: fischer (generated)
+      objectQuotingStrategy: QUOTE_ONLY_RESERVED_WORDS
+      changes:
+        - addColumn:
+            columns:
+              - column:
+                  name: consent_change_count
+                  type: INT
+                  defaultValueNumeric: 0
+            tableName: users
+  - changeSet:
+      id: 1695403516677-2
+      author: fischer (generated)
+      objectQuotingStrategy: QUOTE_ONLY_RESERVED_WORDS
+      changes:
+        - addNotNullConstraint:
+            columnName: consent_change_count
+            tableName: users
+
diff --git a/subato/src/main/resources/db/changelog/db.changelog-master.yaml b/subato/src/main/resources/db/changelog/db.changelog-master.yaml
index d195f3b146269e88e0f431802aeccb0227ad9a8b..c07eb8ee0b0e8d70154a9ccab97557b29620a528 100644
--- a/subato/src/main/resources/db/changelog/db.changelog-master.yaml
+++ b/subato/src/main/resources/db/changelog/db.changelog-master.yaml
@@ -46,4 +46,6 @@ databaseChangeLog:
   - include:
       file: db/changelog/2023/07/05-01-changelog.yaml
   - include:
-      file: db/changelog/2023/09/17-01-changelog.yaml
\ No newline at end of file
+      file: db/changelog/2023/09/17-01-changelog.yaml
+  - include:
+      file: db/changelog/2023/09/22-01-changelog.yaml
\ No newline at end of file