diff --git a/demo/simple_example_auth.py b/demo/simple_example_auth.py
new file mode 100644
index 0000000..d1da45f
--- /dev/null
+++ b/demo/simple_example_auth.py
@@ -0,0 +1,93 @@
+from aiohttp import web
+from aiohttp_session import SimpleCookieStorage, session_middleware
+from aiohttp_security import has_permission, \
+    is_anonymous, remember, forget, \
+    setup as setup_security, SessionIdentityPolicy
+from aiohttp_security.abc import AbstractAuthorizationPolicy
+
+
+# Demo authorization policy for only one user.
+# User 'jack' has only 'listen' permission.
+# For more complicated authorization policies see examples
+# in the 'demo' directory.
+class SimpleJack_AuthorizationPolicy(AbstractAuthorizationPolicy):
+    async def authorized_userid(self, identity):
+        """Retrieve authorized user id.
+        Return the user_id of the user identified by the identity
+        or 'None' if no user exists related to the identity.
+        """
+        if identity == 'jack':
+            return identity
+
+    async def permits(self, identity, permission, context=None):
+        """Check user permissions.
+        Return True if the identity is allowed the permission
+        in the current context, else return False.
+        """
+        return identity == 'jack' and permission in ('listen',)
+
+
+async def handler_root(request):
+    is_logged = not await is_anonymous(request)
+    return web.Response(text='''<html><head></head><body>
+            Hello, I'm Jack, I'm {logged} logged in.<br /><br />
+            <a href="/login">Log me in</a><br />
+            <a href="/logout">Log me out</a><br /><br />
+            Check my permissions,
+            when i'm logged in and logged out.<br />
+            <a href="/listen">Can I listen?</a><br />
+            <a href="/speak">Can I speak?</a><br />
+        </body></html>'''.format(
+            logged='' if is_logged else 'NOT',
+        ), content_type='text/html')
+
+
+async def handler_login_jack(request):
+    redirect_response = web.HTTPFound('/')
+    await remember(request, redirect_response, 'jack')
+    raise redirect_response
+
+
+async def handler_logout(request):
+    redirect_response = web.HTTPFound('/')
+    await forget(request, redirect_response)
+    raise redirect_response
+
+
+@has_permission('listen')
+async def handler_listen(request):
+    return web.Response(body="I can listen!")
+
+
+@has_permission('speak')
+async def handler_speak(request):
+    return web.Response(body="I can speak!")
+
+
+async def make_app():
+    #
+    # WARNING!!!
+    # Never use SimpleCookieStorage on production!!!
+    # It’s highly insecure!!!
+    #
+
+    # make app
+    middleware = session_middleware(SimpleCookieStorage())
+    app = web.Application(middlewares=[middleware])
+
+    # add the routes
+    app.router.add_route('GET', '/', handler_root)
+    app.router.add_route('GET', '/login', handler_login_jack)
+    app.router.add_route('GET', '/logout', handler_logout)
+    app.router.add_route('GET', '/listen', handler_listen)
+    app.router.add_route('GET', '/speak', handler_speak)
+
+    # set up policies
+    policy = SessionIdentityPolicy()
+    setup_security(app, policy, SimpleJack_AuthorizationPolicy())
+
+    return app
+
+
+if __name__ == '__main__':
+    web.run_app(make_app(), port=9000)
diff --git a/docs/example.rst b/docs/example.rst
index b75a8ed..39c839b 100644
--- a/docs/example.rst
+++ b/docs/example.rst
@@ -7,63 +7,96 @@ How to Make a Simple Server With Authorization
 
 Simple example::
 
-    import asyncio
     from aiohttp import web
-
-    async def root_handler(request):
-        text = "Alive and kicking!"
-        return web.Response(body=text.encode('utf-8'))
-
-    # option 2: auth at a higher level?
-    # set user_id and allowed in the wsgi handler
-    @protect('view_user')
-    async def user_handler(request):
-        name = request.match_info.get('name', "Anonymous")
-        text = "Hello, " + name
-        return web.Response(body=text.encode('utf-8'))
+    from aiohttp_session import SimpleCookieStorage, session_middleware
+    from aiohttp_security import has_permission, \
+        is_anonymous, remember, forget, \
+        setup as setup_security, SessionIdentityPolicy
+    from aiohttp_security.abc import AbstractAuthorizationPolicy
 
 
-    # option 3: super low
-    # wsgi doesn't do anything
-    async def user_update_handler(request):
-        # identity, asked_permission
-        user_id = await identity_policy.identify(request)
-        identity = await auth_policy.authorized_userid(user_id)
-        allowed = await request.auth_policy.permits(
-            identity, asked_permission)
-        if not allowed:
-            # how is this pluggable as well?
-            # ? return NotAllowedStream()
-            raise NotAllowedResponse()
+    # Demo authorization policy for only one user.
+    # User 'jack' has only 'listen' permission.
+    # For more complicated authorization policies see examples
+    # in the 'demo' directory.
+    class SimpleJack_AuthorizationPolicy(AbstractAuthorizationPolicy):
+        async def authorized_userid(self, identity):
+            """Retrieve authorized user id.
+            Return the user_id of the user identified by the identity
+            or 'None' if no user exists related to the identity.
+            """
+            if identity == 'jack':
+                return identity
 
-        update_user()
+        async def permits(self, identity, permission, context=None):
+            """Check user permissions.
+            Return True if the identity is allowed the permission
+            in the current context, else return False.
+            """
+            return identity == 'jack' and permission in ('listen',)
 
-    async def init(loop):
-        # set up identity and auth
-        auth_policy = DictionaryAuthorizationPolicy({'me': ('view_user',),
-                                                     'you': ('view_user',
-                                                             'edit_user',)})
-        identity_policy = CookieIdentityPolicy()
-        auth = authorization_middleware(auth_policy, identity_policy)
 
-        # wsgi app
-        app = web.Application(loop=loop, middlewares=*auth)
+    async def handler_root(request):
+        is_logged = not await is_anonymous(request)
+        return web.Response(text='''<html><head></head><body>
+                Hello, I'm Jack, I'm {logged} logged in.<br /><br />
+                <a href="/login">Log me in</a><br />
+                <a href="/logout">Log me out</a><br /><br />
+                Check my permissions,
+                when i'm logged in and logged out.<br />
+                <a href="/listen">Can I listen?</a><br />
+                <a href="/speak">Can I speak?</a><br />
+            </body></html>'''.format(
+                logged='' if is_logged else 'NOT',
+            ), content_type='text/html')
+
+
+    async def handler_login_jack(request):
+        redirect_response = web.HTTPFound('/')
+        await remember(request, redirect_response, 'jack')
+        raise redirect_response
+
+
+    async def handler_logout(request):
+        redirect_response = web.HTTPFound('/')
+        await forget(request, redirect_response)
+        raise redirect_response
+
+
+    @has_permission('listen')
+    async def handler_listen(request):
+        return web.Response(body="I can listen!")
+
+
+    @has_permission('speak')
+    async def handler_speak(request):
+        return web.Response(body="I can speak!")
+
+
+    async def make_app():
+        #
+        # WARNING!!!
+        # Never use SimpleCookieStorage on production!!!
+        # It’s highly insecure!!!
+        #
+
+        # make app
+        middleware = session_middleware(SimpleCookieStorage())
+        app = web.Application(middlewares=[middleware])
 
         # add the routes
-        app.router.add_route('GET', '/', root_handler)
-        app.router.add_route('GET', '/{user}', user_handler)
-        app.router.add_route('GET', '/{user}/edit', user_update_handler)
+        app.router.add_route('GET', '/', handler_root)
+        app.router.add_route('GET', '/login', handler_login_jack)
+        app.router.add_route('GET', '/logout', handler_logout)
+        app.router.add_route('GET', '/listen', handler_listen)
+        app.router.add_route('GET', '/speak', handler_speak)
 
-        # get it started
-        srv = await loop.create_server(app.make_handler(),
-                                       '127.0.0.1', 8080)
-        print("Server started at http://127.0.0.1:8080")
-        return srv
+        # set up policies
+        policy = SessionIdentityPolicy()
+        setup_security(app, policy, SimpleJack_AuthorizationPolicy())
+
+        return app
 
 
-    loop = asyncio.get_event_loop()
-    loop.run_until_complete(init(loop))
-    try:
-        loop.run_forever()
-    except KeyboardInterrupt:
-        pass  # TODO put handler cleanup here
+    if __name__ == '__main__':
+        web.run_app(make_app(), port=9000)