diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 1b9b4ce4370613e680a4cff72000dc8a08de97cf..48ab4603dc4d7ff9c1c29c715ccc4eac434b1b05 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -48,6 +48,7 @@ import {
   MatTooltipModule
 } from '@angular/material';
 import { HTTP_INTERCEPTORS, HttpClient, HttpClientModule } from '@angular/common/http';
+import { UserService } from './services/http/user.service';
 import { RoomPageComponent } from './components/pages/room-page/room-page.component';
 import { RoomCreateComponent } from './components/dialogs/room-create/room-create.component';
 import { LoginComponentPageComponent } from './components/pages/login-page/login-page.component';
@@ -70,6 +71,7 @@ import { ContentAnswerService } from './services/http/content-answer.service';
 import { RoomDeleteComponent } from './components/dialogs/room-delete/room-delete.component';
 import { StatisticsComponent } from './components/fragments/statistics/statistics.component';
 import { RoomEditComponent } from './components/dialogs/room-edit/room-edit.component';
+import { UserActivationComponent } from './components/dialogs/user-activation/user-activation.component';
 import { ContentChoiceParticipantComponent } from './components/fragments/content-choice-participant/content-choice-participant.component';
 import { ContentChoiceCreatorComponent } from './components/fragments/content-choice-creator/content-choice-creator.component';
 import { ContentCreatePageComponent } from './components/pages/content-create-page/content-create-page.component';
@@ -119,6 +121,7 @@ import { FooterImprintComponent } from './components/pages/footer-imprint/footer
     AnswersListComponent,
     RoomDeleteComponent,
     RoomEditComponent,
+    UserActivationComponent,
     ContentChoiceParticipantComponent,
     ContentChoiceCreatorComponent,
     ContentCreatePageComponent,
@@ -145,6 +148,7 @@ import { FooterImprintComponent } from './components/pages/footer-imprint/footer
     RoomCreateComponent,
     RoomDeleteComponent,
     RoomEditComponent,
+    UserActivationComponent,
     AnswerEditComponent,
     ContentChoiceCreatorComponent,
     ContentLikertCreatorComponent,
@@ -217,6 +221,7 @@ import { FooterImprintComponent } from './components/pages/footer-imprint/footer
     CommentService,
     ContentService,
     ContentAnswerService,
+    UserService,
     {
       provide: MatDialogRef,
       useValue: {
diff --git a/src/app/components/dialogs/user-activation/user-activation.component.html b/src/app/components/dialogs/user-activation/user-activation.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..ae7952cd12b1e6b663036f0e20bafac232074c64
--- /dev/null
+++ b/src/app/components/dialogs/user-activation/user-activation.component.html
@@ -0,0 +1,9 @@
+<form (ngSubmit)="login(userActivationKey.value)" fxLayout="column" fxLayoutAlign="space-around"
+      fxLayoutGap="10px">
+  <mat-form-field class="input-block">
+    <input matInput #userActivationKey type="text" placeholder="{{ 'login.activation-key' | translate }}"
+           [formControl]="activationKeyFormControl" [errorStateMatcher]="matcher" name="activation-key"/>
+    <mat-error *ngIf="activationKeyFormControl.hasError('required')">{{ 'login.activation-key-required' | translate }}</mat-error>
+  </mat-form-field>
+  <button mat-raised-button color="primary" type="submit">{{ 'login.activate' | translate }}</button>
+</form>
diff --git a/src/app/components/dialogs/user-activation/user-activation.component.scss b/src/app/components/dialogs/user-activation/user-activation.component.scss
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/app/components/dialogs/user-activation/user-activation.component.ts b/src/app/components/dialogs/user-activation/user-activation.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c7074043db7683842aee57b876cdf2fa5b24da7e
--- /dev/null
+++ b/src/app/components/dialogs/user-activation/user-activation.component.ts
@@ -0,0 +1,33 @@
+import { Component, Inject, OnInit} from '@angular/core';
+import { NotificationService } from '../../../services/util/notification.service';
+import { UserService } from '../../../services/http/user.service';
+import { FormControl, Validators} from '@angular/forms';
+import { MAT_DIALOG_DATA } from '@angular/material';
+
+@Component({
+  selector: 'app-user-activation',
+  templateUrl: './user-activation.component.html',
+  styleUrls: ['./user-activation.component.scss']
+})
+export class UserActivationComponent implements OnInit {
+
+  activationKeyFormControl = new FormControl('', [Validators.required]);
+
+  constructor(
+    @Inject(MAT_DIALOG_DATA) public data: any,
+    public userService: UserService,
+    public notificationService: NotificationService
+  ) {
+  }
+
+  ngOnInit() {
+  }
+
+  login(activationKey: string): void {
+    activationKey = activationKey.trim();
+
+    this.userService.activate(this.data.name.trim(), activationKey).subscribe(ret => {
+      console.log(ret);
+    });
+  }
+}
diff --git a/src/app/components/fragments/login/login.component.ts b/src/app/components/fragments/login/login.component.ts
index 2eabb04fb7cda3a81ed84e01191f98f620ae8e1a..0207ef26b89b5f9dd3e7989051e21f86a1d7b03a 100644
--- a/src/app/components/fragments/login/login.component.ts
+++ b/src/app/components/fragments/login/login.component.ts
@@ -2,10 +2,11 @@ import { Component, Input, OnInit } from '@angular/core';
 import { AuthenticationService } from '../../../services/http/authentication.service';
 import { Router } from '@angular/router';
 import { NotificationService } from '../../../services/util/notification.service';
-import { ErrorStateMatcher } from '@angular/material';
+import { ErrorStateMatcher, MatDialog} from '@angular/material';
 import { FormControl, FormGroupDirective, NgForm, Validators } from '@angular/forms';
 import { UserRole } from '../../../models/user-roles.enum';
 import { TranslateService } from '@ngx-translate/core';
+import { UserActivationComponent } from '../../dialogs/user-activation/user-activation.component';
 
 export class LoginErrorStateMatcher implements ErrorStateMatcher {
   isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
@@ -27,16 +28,20 @@ export class LoginComponent implements OnInit {
 
   matcher = new LoginErrorStateMatcher();
 
+  name = '';
+
   constructor(public authenticationService: AuthenticationService,
               public router: Router,
               private translationService: TranslateService,
-              public notificationService: NotificationService) {
+              public notificationService: NotificationService,
+              public dialog: MatDialog) {
   }
 
   ngOnInit() {
   }
 
   login(username: string, password: string): void {
+    this.name = username;
     username = username.trim();
     password = password.trim();
 
@@ -54,14 +59,21 @@ export class LoginComponent implements OnInit {
     this.authenticationService.guestLogin(this.role).subscribe(loginSuccessful => this.checkLogin(loginSuccessful));
   }
 
-  private checkLogin(loginSuccessful: boolean) {
-    if (loginSuccessful) {
+  private checkLogin(loginSuccessful: string) {
+    if (loginSuccessful === 'true') {
       this.notificationService.show('Login successful!');
       if (this.role === UserRole.CREATOR) {
         this.router.navigate(['creator']);
       } else {
         this.router.navigate(['participant']);
       }
+    } else if (loginSuccessful === 'activation') {
+      this.dialog.open(UserActivationComponent, {
+        width: '350px',
+        data: {
+          name: this.name
+        }
+      });
     } else {
       this.translationService.get('login.login-data-incorrect').subscribe(message => {
         this.notificationService.show(message);
diff --git a/src/app/services/http/authentication.service.ts b/src/app/services/http/authentication.service.ts
index 415c5f80ff46ed564fa4bd8e0a136c53364a6602..6fff4d3850d25769ccfb3a35e067f9a607bf77ac 100644
--- a/src/app/services/http/authentication.service.ts
+++ b/src/app/services/http/authentication.service.ts
@@ -35,7 +35,13 @@ export class AuthenticationService {
     }
   }
 
-  login(email: string, password: string, userRole: UserRole): Observable<boolean> {
+  /*
+   * Three possible return values:
+   * - "true": login successful
+   * - "false": login failed
+   * - "activation": account exists but needs activation with key
+   */
+  login(email: string, password: string, userRole: UserRole): Observable<string> {
     const connectionUrl: string = this.apiUrl.base + this.apiUrl.auth + this.apiUrl.login + this.apiUrl.registered;
 
     return this.checkLogin(this.http.post<ClientAuthentication>(connectionUrl, {
@@ -44,7 +50,7 @@ export class AuthenticationService {
     }, this.httpOptions), userRole, false);
   }
 
-  guestLogin(userRole: UserRole): Observable<boolean> {
+  guestLogin(userRole: UserRole): Observable<string> {
     const connectionUrl: string = this.apiUrl.base + this.apiUrl.auth + this.apiUrl.login + this.apiUrl.guest;
 
     return this.checkLogin(this.http.post<ClientAuthentication>(connectionUrl, null, this.httpOptions), userRole, true);
@@ -99,7 +105,7 @@ export class AuthenticationService {
     return this.isLoggedIn() ? this.user.getValue().token : undefined;
   }
 
-  private checkLogin(clientAuthentication: Observable<ClientAuthentication>, userRole: UserRole, isGuest: boolean): Observable<boolean> {
+  private checkLogin(clientAuthentication: Observable<ClientAuthentication>, userRole: UserRole, isGuest: boolean): Observable<string> {
     return clientAuthentication.map(result => {
       if (result) {
         this.setUser(new User(
@@ -109,12 +115,16 @@ export class AuthenticationService {
           result.token,
           userRole,
           isGuest));
-        return true;
+        return 'true';
       } else {
-        return false;
+        return 'false';
       }
-    }).catch(() => {
-      return of(false);
+    }).catch((e) => {
+      // check if user needs activation
+      if (e.error.errorType === 'DisabledException') {
+        return of('activation');
+      }
+      return of('false');
     });
   }
 
diff --git a/src/app/services/http/user.service.ts b/src/app/services/http/user.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..29b400306fd2a668af60aacaa834d31e0045567f
--- /dev/null
+++ b/src/app/services/http/user.service.ts
@@ -0,0 +1,32 @@
+import { Injectable } from '@angular/core';
+import { User } from '../../models/user';
+import { Observable } from 'rxjs/Observable';
+import { of } from 'rxjs/observable/of';
+import { HttpClient, HttpHeaders } from '@angular/common/http';
+import { ClientAuthentication } from '../../models/client-authentication';
+import { BaseHttpService } from './base-http.service';
+
+const httpOptions = {
+  headers: new HttpHeaders({})
+};
+
+@Injectable()
+export class UserService extends BaseHttpService {
+  private apiUrl = {
+    base: '/api',
+    user: '/user',
+    activate: '/activate'
+  };
+
+  constructor(private http: HttpClient) {
+    super();
+  }
+
+  activate(name: string, activationKey: string): Observable<string> {
+    const connectionUrl: string = this.apiUrl.base + this.apiUrl.user + '/~' + encodeURIComponent(name) + this.apiUrl.activate;
+
+    return this.http.post<string>(connectionUrl, {
+        key: activationKey
+      }, httpOptions);
+  }
+}
diff --git a/src/assets/i18n/de.json b/src/assets/i18n/de.json
index 9a29da1d22b9880540320e56190cce9772dc39a9..8358928461faf2377b915541cb555a488427461c 100644
--- a/src/assets/i18n/de.json
+++ b/src/assets/i18n/de.json
@@ -19,7 +19,10 @@
 		"login": "Anmelden",
 		"login-data-incorrect": "Benutzername oder Passwort nicht korrekt.",
 		"password": "Passwort",
-		"password-required": "Passwort ist erforderlich"
+		"password-required": "Passwort ist erforderlich",
+    "activate": "Aktivieren",
+    "activation-key": "Aktivierungsschlüssel",
+    "activation-key-required": "Aktivierungsschlüssel erforderlich"
 	},
 	"password-reset": {
 		"email": "E-Mail",
diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json
index 745c2e809b9bb35720b46ac6171a1ae8d8f5df2e..96ac280e89deed8c8f23cd5dbe4a69d3fbf476ba 100644
--- a/src/assets/i18n/en.json
+++ b/src/assets/i18n/en.json
@@ -19,7 +19,10 @@
 		"login": "Login",
 		"login-data-incorrect": "Username or password incorrect.",
 		"password": "Password",
-		"password-required": "Password is required"
+		"password-required": "Password is required",
+    "activate": "Activate",
+    "activation-key": "Activation key",
+    "activation-key-required": "Activation key required"
 	},
 	"password-reset": {
 		"email": "E-Mail",