diff --git a/source/calendarwebapp/authenticator.d b/source/calendarwebapp/authenticator.d
index 6607f1f..cf97d60 100644
--- a/source/calendarwebapp/authenticator.d
+++ b/source/calendarwebapp/authenticator.d
@@ -2,14 +2,18 @@ module calendarwebapp.authenticator;
 
 import poodinis;
 
+import std.range : InputRange;
 import std.typecons : nullable, Nullable;
 
-import vibe.data.bson : Bson, BsonObjectID, deserializeBson;
+import vibe.data.bson;
 import vibe.db.mongo.collection : MongoCollection;
 
 interface Authenticator
 {
     Nullable!AuthInfo checkUser(string username, string password) @safe;
+    void addUser(AuthInfo authInfo) @safe;
+    InputRange!AuthInfo getAllUsers() @safe;
+    void removeUser(BsonObjectID id) @safe;
 }
 
 class MongoDBAuthenticator(Collection = MongoCollection) : Authenticator
@@ -35,7 +39,28 @@ public:
                 return authInfo.nullable;
             }
         }
-        return Nullable!AuthInfo();
+        return Nullable!AuthInfo.init;
+    }
+
+    void addUser(AuthInfo authInfo) @safe
+    {
+        if (!authInfo.id.valid)
+            authInfo.id = BsonObjectID.generate;
+
+        users.insert(authInfo.serializeToBson);
+    }
+
+    InputRange!AuthInfo getAllUsers() @safe
+    {
+        import std.algorithm : map;
+        import std.range : inputRangeObject;
+
+        return users.find().map!(deserializeBson!AuthInfo).inputRangeObject;
+    }
+
+    void removeUser(BsonObjectID id) @safe
+    {
+        users.remove(["_id" : id]);
     }
 }
 
@@ -75,5 +100,4 @@ private:
         }
         return ret;
     }
-
 }
diff --git a/source/calendarwebapp/calendarwebapp.d b/source/calendarwebapp/calendarwebapp.d
index 8427942..7bcc1ff 100644
--- a/source/calendarwebapp/calendarwebapp.d
+++ b/source/calendarwebapp/calendarwebapp.d
@@ -1,6 +1,8 @@
 module calendarwebapp.calendarwebapp;
 
-import calendarwebapp.authenticator : Authenticator, AuthInfo;
+import botan.rng.rng : RandomNumberGenerator;
+
+import calendarwebapp.authenticator : Authenticator, AuthInfo, Privilege = Role;
 import calendarwebapp.event;
 
 import core.time : days;
@@ -23,12 +25,12 @@ import vibe.web.web : errorDisplay, noRoute, redirect, render, SessionVar,
 {
     @noRoute AuthInfo authenticate(scope HTTPServerRequest req, scope HTTPServerResponse) @safe
     {
-        if (!req.session || !req.session.isKeySet("auth"))
+        if (!req.session || !req.session.isKeySet("authInfo"))
         {
             redirect("/login");
             return AuthInfo.init;
         }
-        return req.session.get!AuthInfo("auth");
+        return req.session.get!AuthInfo("authInfo");
     }
 
 public:
@@ -47,7 +49,7 @@ public:
     {
         auto authInfo = authenticator.checkUser(username, password);
         enforce(!authInfo.isNull, "Benutzername oder Passwort ungültig");
-        auth = authInfo.get;
+        this.authInfo = authInfo.get;
         redirect("/");
     }
 
@@ -57,12 +59,12 @@ public:
         redirect("/");
     }
 
-    @anyAuth void getCreate(ValidationErrorData _error = ValidationErrorData.init)
+    @anyAuth void getCreateevent(ValidationErrorData _error = ValidationErrorData.init)
     {
-        render!("create.dt", _error);
+        render!("createevent.dt", _error);
     }
 
-    @anyAuth @errorDisplay!getCreate void postCreate(Date begin,
+    @anyAuth @errorDisplay!getCreateevent void postCreateevent(Date begin,
             Nullable!Date end, string description, string name, EventType type, bool shout) @safe
     {
         import std.array : replace, split;
@@ -78,12 +80,39 @@ public:
         redirect("/");
     }
 
-    @anyAuth void postRemove(BsonObjectID id) @safe
+    @anyAuth void postRemoveevent(BsonObjectID id) @safe
     {
         eventStore.removeEvent(id);
         redirect("/");
     }
 
+    @auth(Role.admin) void getUsers()
+    {
+        auto users = authenticator.getAllUsers;
+        render!("showusers.dt", users);
+    }
+
+    @auth(Role.admin) void postRemoveuser(BsonObjectID id) @safe
+    {
+        authenticator.removeUser(id);
+        redirect("/users");
+    }
+
+    @auth(Role.admin) void getCreateuser(ValidationErrorData _error = ValidationErrorData.init)
+    {
+        render!("createuser.dt", _error);
+    }
+
+    @auth(Role.admin) @errorDisplay!getCreateuser void postCreateuser(string username,
+            string password, Privilege role)
+    {
+        import botan.passhash.bcrypt;
+
+        authenticator.addUser(AuthInfo(BsonObjectID.generate, username,
+                generateBcrypt(password, rng, 10), role));
+        redirect("/users");
+    }
+
 private:
     struct ValidationErrorData
     {
@@ -91,8 +120,9 @@ private:
         string field;
     }
 
-    SessionVar!(AuthInfo, "auth") auth;
+    SessionVar!(AuthInfo, "authInfo") authInfo;
 
     @Autowire EventStore eventStore;
     @Autowire Authenticator authenticator;
+    @Autowire RandomNumberGenerator rng;
 }
diff --git a/source/calendarwebapp/configuration.d b/source/calendarwebapp/configuration.d
index c2c0959..6a33e86 100644
--- a/source/calendarwebapp/configuration.d
+++ b/source/calendarwebapp/configuration.d
@@ -1,5 +1,8 @@
 module calendarwebapp.configuration;
 
+import botan.rng.auto_rng : AutoSeededRNG;
+import botan.rng.rng : RandomNumberGenerator;
+
 import calendarwebapp.authenticator : Authenticator, MongoDBAuthenticator;
 import calendarwebapp.calendarwebapp : CalendarWebapp;
 import calendarwebapp.event : EventStore, MongoDBEventStore;
@@ -19,6 +22,7 @@ public:
         container.register!MongoClient.existingInstance(mongoClient);
         container.register!(EventStore, MongoDBEventStore!());
         container.register!(Authenticator, MongoDBAuthenticator!());
+        container.register!(RandomNumberGenerator, AutoSeededRNG);
         container.register!CalendarWebapp;
         container.register!(ValueInjector!string, StringInjector);
         container.register!(ValueInjector!MongoCollection, MongoCollectionInjector);
diff --git a/test/calendarwebapp/testauthenticator.d b/test/calendarwebapp/testauthenticator.d
index 48addc1..c672b09 100644
--- a/test/calendarwebapp/testauthenticator.d
+++ b/test/calendarwebapp/testauthenticator.d
@@ -11,7 +11,10 @@ import vibe.data.bson : Bson, BsonObjectID;
 
 interface Collection
 {
+    Bson[] find() @safe;
     Bson findOne(string[string] query) @safe;
+    void insert(Bson document) @safe;
+    void remove(BsonObjectID[string] selector) @safe;
 }
 
 class CollectionInjector : ValueInjector!Collection
diff --git a/views/create.dt b/views/createevent.dt
similarity index 97%
rename from views/create.dt
rename to views/createevent.dt
index 19f8e53..d3ec627 100644
--- a/views/create.dt
+++ b/views/createevent.dt
@@ -3,7 +3,7 @@ block content
 	- void showerror(string field = null)
 		- if (_error.msg && _error.field == field)
 			td.error= _error.msg
-	form(action="/create", method="post")
+	form(action="/createevent", method="post")
 		fieldset(name="eventFields")
 			table
 				tbody#fieldTable
diff --git a/views/createuser.dt b/views/createuser.dt
new file mode 100644
index 0000000..79c9670
--- /dev/null
+++ b/views/createuser.dt
@@ -0,0 +1,32 @@
+extends layout
+block content
+	- void showerror(string field = null)
+		- if (_error.msg && _error.field == field)
+			td.error= _error.msg
+	form(action="/createuser", method="post")
+		fieldset(name="eventFields")
+			table
+				tbody#fieldTable
+					tr
+						td
+							label(for="username") Benutzername
+						td
+							input#username(value="", name="username", type="text")
+						- showerror("username");
+					tr
+						td
+							label(for="password") Passwort
+						td
+							input#password(value="", name="password", type="password")
+					tr
+						td
+							label(for="role") Rolle
+						td
+							select#type(name="role")
+								option(value="User") Benutzer
+								option(value="Admin") Administrator
+						- showerror("role");
+				tfoot
+					tr
+						td(colspan="2")
+							input#submitButton(type="submit", value="Ereignis erstellen")
\ No newline at end of file
diff --git a/views/navigation.dt b/views/navigation.dt
index e7719aa..bec6532 100644
--- a/views/navigation.dt
+++ b/views/navigation.dt
@@ -3,6 +3,10 @@ nav
 		li
 			a(href='/') Home
 		li
-			a(href='/create') Ereignis erstellen 
+			a(href='/createevent') Ereignis erstellen
+		li
+			a(href='/users') Benutzerliste
+		li
+			a(href='/createuser') Benutzer erstellen
 		li
 			a(href='/logout') Ausloggen
\ No newline at end of file
diff --git a/views/showevents.dt b/views/showevents.dt
index 8592840..59e2b5c 100644
--- a/views/showevents.dt
+++ b/views/showevents.dt
@@ -24,7 +24,7 @@ block content
 			tr
 				td shout
 				td #{event.shout}
-		form(action="/remove", method="post")
+		form(action="/removeevent", method="post")
 			input#id(value="#{event.id}", name="id", type="hidden")
 			input#submitButton(type="submit", value="Entfernen")
 		hr
diff --git a/views/showusers.dt b/views/showusers.dt
new file mode 100644
index 0000000..749dbae
--- /dev/null
+++ b/views/showusers.dt
@@ -0,0 +1,18 @@
+extends layout.dt
+block content
+	h1 Users
+	- foreach (user; users)
+		table
+			tr
+				td id
+				td #{user.id}
+			tr
+				td username
+				td #{user.username}
+			tr
+				td role
+				td #{user.role}
+		form(action="/removeuser", method="post")
+			input#id(value="#{user.id}", name="id", type="hidden")
+			input#submitButton(type="submit", value="Entfernen")
+		hr