diff --git a/res_users.py b/res_users.py
index 29ff14e288ef835341c8b458cf7aa88046507266_cmVzX3VzZXJzLnB5..06ccd421baba44872336dab75fb8bc4a9e4f769f_cmVzX3VzZXJzLnB5 100644
--- a/res_users.py
+++ b/res_users.py
@@ -1,3 +1,4 @@
+# -*- encoding: utf-8 -*-
 import logging
 import lasso
 
@@ -20,10 +21,6 @@
             'SAML User ID',
             help="SAML Provider user_id",
         ),
-        'saml_access_token': fields.char(
-            'Current SAML token for this user',
-            help="The current SAML token in use",
-        ),
     }
 
     _sql_constraints = [
@@ -53,6 +50,4 @@
             raise Exception('Invalid assertion')
 
         # TODO use a real token validation from LASSO
-        validation = {}
-
         # TODO push into the validation result a real UPN
@@ -58,5 +53,5 @@
         # TODO push into the validation result a real UPN
-        validation['user_id'] = login.assertion.subject.nameId.content
+        validation = {'user_id': login.assertion.subject.nameId.content}
 
         """
         if p.data_endpoint:
@@ -80,6 +75,7 @@
 
             This method can be overridden to add alternative signin methods.
         """
+        token_osv = self.pool.get('auth_saml.token')
         saml_uid = validation['user_id']
 
         user_ids = self.search(
@@ -97,4 +93,5 @@
         # production code...
         assert len(user_ids) == 1
 
+        # browse the user because we'll need this in the response
         user = self.browse(cr, uid, user_ids[0], context=context)
@@ -100,9 +97,31 @@
         user = self.browse(cr, uid, user_ids[0], context=context)
-        # WARNING: writing this means you can only log-in once with a single
-        # user...
-        # TODO add a new table with access tokens linked to users
-        # in order to be able to log multiple times with the same user
-        user.write({'saml_access_token': saml_response})
+
+        user_id = user.id
+
+        # now find if a token for this user/provider already exists
+        token_ids = token_osv.search(
+            cr, uid,
+            [
+                ('saml_provider_id', '=', provider),
+                ('user_id', '=', user_id),
+            ]
+        )
+        if token_ids:
+            token_osv.write(
+                cr, uid, token_ids,
+                {'saml_access_token': saml_response},
+                context=context
+            )
+        else:
+            token_osv.create(
+                cr, uid,
+                {
+                    'saml_access_token': saml_response,
+                    'saml_provider_id': provider,
+                    'user_id': user_id,
+                },
+                context=context
+            )
 
         return user.login
 
@@ -125,10 +144,10 @@
             raise openerp.exceptions.AccessDenied()
 
         # return user credentials
-        return (cr.dbname, login, saml_response)
+        return cr.dbname, login, saml_response
 
     def check_credentials(self, cr, uid, token):
         """token can be a password if the user has used the normal form...
         but we are more interested in the case when they are tokens
         and the interesting code is inside the except clause
         """
@@ -129,7 +148,8 @@
 
     def check_credentials(self, cr, uid, token):
         """token can be a password if the user has used the normal form...
         but we are more interested in the case when they are tokens
         and the interesting code is inside the except clause
         """
+        token_osv = self.pool.get('auth_saml.token')
         try:
@@ -135,4 +155,4 @@
         try:
-            return super(res_users, self).check_credentials(cr, uid, token)
+            super(res_users, self).check_credentials(cr, uid, token)
 
         except openerp.exceptions.AccessDenied:
@@ -137,5 +157,7 @@
 
         except openerp.exceptions.AccessDenied:
-            res = self.search(
+            # since normal auth did not succeed we now try to find if the user
+            # has an active token attached to his uid
+            res = token_osv.search(
                 cr, SUPERUSER_ID,
                 [
@@ -140,7 +162,7 @@
                 cr, SUPERUSER_ID,
                 [
-                    ('id', '=', uid),
+                    ('user_id', '=', uid),
                     ('saml_access_token', '=', token),
                 ]
             )
 
@@ -143,6 +165,7 @@
                     ('saml_access_token', '=', token),
                 ]
             )
 
+            # if the user is not found we re-raise the AccessDenied
             if not res:
                 # TODO: maybe raise a defined exception instead of the last
@@ -147,4 +170,4 @@
             if not res:
                 # TODO: maybe raise a defined exception instead of the last
-                # exception that occured in our execution frame
+                # exception that occurred in our execution frame
                 raise
diff --git a/token.py b/token.py
new file mode 100644
index 0000000000000000000000000000000000000000..06ccd421baba44872336dab75fb8bc4a9e4f769f_dG9rZW4ucHk=
--- /dev/null
+++ b/token.py
@@ -0,0 +1,31 @@
+# -*- encoding: utf-8 -*-
+__author__ = 'faide'
+
+
+import logging
+from openerp.osv import osv, fields
+
+_logger = logging.getLogger(__name__)
+
+
+class saml_token(osv.Model):
+    _name = "auth_saml.token"
+    _rec_name = "user_id"
+
+    _columns = {
+        'saml_provider_id': fields.many2one(
+            'auth.saml.provider',
+            string='SAML Provider that issued the token',
+        ),
+        'user_id': fields.many2one(
+            'res.users',
+            string="User",
+            # we want the token to be destroyed if the corresponding res.users
+            # is deleted
+            ondelete="cascade"
+        ),
+        'saml_access_token': fields.char(
+            'Current SAML token for this user',
+            help="The current SAML token in use",
+        ),
+    }