api for adding a new user+otp

148 views
Skip to first unread message

Paolo

unread,
Oct 23, 2014, 11:46:15 AM10/23/14
to priva...@googlegroups.com
Is it possible to add a new user with a custom python script? (I need to dynamically add users to privacyidea upon a registration...

corneliu...@netknights.it

unread,
Oct 23, 2014, 5:18:48 PM10/23/14
to priva...@googlegroups.com
Hallo Paolo,

I guess you are talking of users and not administrators?

privacyidea does not manage the users.
It reads users from sql databases, flat files, scim services or ldap services.
So if you are doing user registration, the user registration application should create a new user in your sql database.

You should set up a userresolver and realm, that points to this user table in your sql database. If the user registered succesfully you will then see the new user in privacyidea.

Kind regards
Cornelius

corneliu...@netknights.it

unread,
Oct 23, 2014, 5:24:04 PM10/23/14
to priva...@googlegroups.com
PS: If you registration script created the new user in the database is visible in privacyidea, you can very well create a new token for this new user.
You may use the API to do this. The web API of interest is /admin/init.
Take a look at http://api.privacyidea.org.
You are interested in the admin-controller: http://api.privacyidea.org/privacyidea.controllers.admin.AdminController-class.html

You may also take a look at the command line client, you will get an idea, how to do such a request in a python command line script.
https://github.com/privacyidea/privacyideaadm/blob/master/scripts/privacyidea#L386

Paolo

unread,
Oct 30, 2014, 3:57:16 AM10/30/14
to priva...@googlegroups.com
Can I add a token using a JSON get/post request?

corneliu...@netknights.it

unread,
Oct 30, 2014, 7:33:24 AM10/30/14
to priva...@googlegroups.com
Hallo Paolo,

yes, you can.

You can add a single token by issuing a comand like

/admin/init?serial=12345678&type=TOTP&otpkey=a3c687f5ff...

You provide the tokentype (default is hmac), the serial number and the otpkey, which is in hex form.

You can also upload a file via the API, which is a bit more complicated... (http://api.privacyidea.org/privacyidea.controllers.admin.AdminController-class.html#loadtokens)
The type would be "aladdin-xml" or "oathcsv".

Kind regards
COrnelius

Paolo

unread,
Oct 30, 2014, 9:53:09 AM10/30/14
to priva...@googlegroups.com
Hello, thanks a lot for your time, your very kind :)
However I still have another problem because, when I try your request, I always receive a <Response [576]> and no token is being added!

corneliu...@netknights.it

unread,
Oct 30, 2014, 5:02:27 PM10/30/14
to priva...@googlegroups.com
You need to provide the username and password of an administrator.
Honestly it is a bit tricky:

1. Call
    https://privacyidea/account/dologin?login=admin&realm=admin&password=yourpassword
  You may call it as a post request...
  The important part is, you get a cookie called "privacyidea_session".

2. Now you need to pass this cookie as cookie and also the contents of the cookie
   in the html paramter "session".

You are welcome to ask again - since in fact it is a bit tricky ;-)

Kind regards
Cornelius

Message has been deleted

Cornelius Kölbel

unread,
Oct 31, 2014, 1:51:29 AM10/31/14
to priva...@googlegroups.com

Am 31.10.2014 um 00:05 schrieb Paolo:
Hello :)
with this script I save the content of the response cookie to a file:

s = requests.Session()
s.cookies = LWPCookieJar('cookiejar')
if not os.path.exists('cookiejar'):
    print('setting cookies')
    s.cookies.save()

s.cookies.save(ignore_discard=True)

file content:

#LWP-Cookies-2.0
Set-Cookie3: privacyidea_session="\"cd894d49ff6396f48b249a14783782110552c0bcUSERNAME!\""; path="/"; domain="localhost.local"; path_spec; discard; version=0

Now what I have to do is the number 1 or the number 2??
  1. send a POST/GET request to https://localhost:5001/admin/init?serial=12345678&type=TOTP&genkey=1 with the cookie (sending the file)
  2. send a POST/GET request to https://localhost:5001/admin/init?serial=12345678&type=TOTP&genkey=1&session=cd894d49ff6396f48b249a14783782110552c0bcUSERNAME! (adding the privacyidea_session as a url parameter)
Thanks a lot again :)

Hi Paolo,
You need to do second one.
I am sorry, I forgot to tell you that you can take a look at the code of the command line admin client.

First you can login:
https://github.com/privacyidea/privacyideaadm/blob/master/privacyideautils/clientutils.py#L344
(it stores the session in self.session and the cookie in self.cookie_jar)

Then you can call the function you are interested in:
https://github.com/privacyidea/privacyideaadm/blob/master/privacyideautils/clientutils.py#L302
with the stored session and the cookie.

Kind  regards
Cornelius






signature.asc

Paolo

unread,
Oct 31, 2014, 9:32:13 AM10/31/14
to priva...@googlegroups.com
Hello, 
thanks :)
Now I have a small problem when I try to get the OTP value:
{
   "version": "privacyIDEA 1.5dev6", 
   "jsonrpc": "2.0", 
   "result": {
      "status": false, 
      "error": {
         "message": "gettoken/getotp failed: 'NoneType' object has no attribute 'lower'", 
         "code": -311
      }
   }, 
   "id": 0
}

I'm doing this request:
r = s.get('https://localhost:5001/gettoken/getotp?user=USER&realm=REALM&serial=SERIAL&session=SESSION_ID', verify=False)

What am I missing?
Thanks a lot again!
I owe you a beer. If you come to Italy inform me ;)

Cornelius Kölbel

unread,
Oct 31, 2014, 9:59:03 AM10/31/14
to priva...@googlegroups.com
HI Paolo,

first, you can omit the user and realm if you provide the serial number.
The serial number will always identify the token directly.

The error message come from "somewhere deeper".
It might be, because the tokentype does not support getotp.
Can you provide the traceback in /var/log/privacyidea/privacyidea.log?

I will thankfully take the beer! ;-)

Kind regards
Cornelius
--
You received this message because you are subscribed to the Google Groups "privacyidea" group.
To unsubscribe from this group and stop receiving emails from it, send an email to privacyidea...@googlegroups.com.
To post to this group, send email to priva...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/privacyidea/3762c92e-81db-46db-8d2d-049acff05266%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

signature.asc

Paolo

unread,
Oct 31, 2014, 12:38:25 PM10/31/14
to priva...@googlegroups.com
The first error I got is this:
{
   "version": "privacyIDEA 1.5dev6", 
   "jsonrpc": "2.0", 
   "result": {
      "status": false, 
      "error": {
         "message": "The policy forbids receiving OTP values for the token 12345678 in this realm", 
         "code": -311
      }
   }, 
   "id": 1
}

I tried some things and I saw that setting the policy gettoken with the param max_count_hotp=1 will solve the abovementioned problem :)
But then if I try again with another request I get the message I wrote in the previous post :(
This is the content of the log file:

2014/10/31 - 17:35:23 ERROR {140182842357504} [privacyidea.controllers.gettoken][getotp #315] gettoken/getotp failed: AttributeError("'NoneType' object has no attribute 'lower'",)
2014/10/31 - 17:35:23 ERROR {140182842357504} [privacyidea.controllers.gettoken][getotp #315] gettoken/getotp failed: AttributeError("'NoneType' object has no attribute 'lower'",)
2014/10/31 - 17:35:23 ERROR {140182842357504} [privacyidea.controllers.gettoken][getotp #316] Traceback (most recent call last):
  File "/usr/lib/python2.7/dist-packages/privacyidea/controllers/gettoken.py", line 276, in getotp
    tokenrealms=tokenrealms)
  File "/usr/lib/python2.7/dist-packages/privacyidea/lib/log.py", line 95, in wrapper
    f_result = func(*args, **kwds)
  File "/usr/lib/python2.7/dist-packages/privacyidea/lib/policy.py", line 1553, in checkPolicyPre
    'user': admin_user['login']})
  File "/usr/lib/python2.7/dist-packages/privacyidea/lib/log.py", line 95, in wrapper
    f_result = func(*args, **kwds)
  File "/usr/lib/python2.7/dist-packages/privacyidea/lib/policy.py", line 248, in getPolicy
    for p in policy.get('user').lower().split(',')]
AttributeError: 'NoneType' object has no attribute 'lower'

2014/10/31 - 17:35:23 ERROR {140182842357504} [privacyidea.controllers.gettoken][getotp #316] Traceback (most recent call last):
  File "/usr/lib/python2.7/dist-packages/privacyidea/controllers/gettoken.py", line 276, in getotp
    tokenrealms=tokenrealms)
  File "/usr/lib/python2.7/dist-packages/privacyidea/lib/log.py", line 95, in wrapper
    f_result = func(*args, **kwds)
  File "/usr/lib/python2.7/dist-packages/privacyidea/lib/policy.py", line 1553, in checkPolicyPre
    'user': admin_user['login']})
  File "/usr/lib/python2.7/dist-packages/privacyidea/lib/log.py", line 95, in wrapper
    f_result = func(*args, **kwds)
  File "/usr/lib/python2.7/dist-packages/privacyidea/lib/policy.py", line 248, in getPolicy
    for p in policy.get('user').lower().split(',')]
AttributeError: 'NoneType' object has no attribute 'lower'

Cornelius Kölbel

unread,
Oct 31, 2014, 12:51:48 PM10/31/14
to priva...@googlegroups.com
Hi Paolo,

huch. Your policy has no user defined. This is why the line


    for p in policy.get('user').lower().split(',')]

fails.

So change your policy to include a "user": "*".

This will fix the problem for now.

Kind regards
Cornelius
--
You received this message because you are subscribed to the Google Groups "privacyidea" group.
To unsubscribe from this group and stop receiving emails from it, send an email to privacyidea...@googlegroups.com.
To post to this group, send email to priva...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

-- 
Cornelius Kölbel
corneliu...@netknights.it
+49 151 2960 1417

NetKnights GmbH
http://www.netknights.it
Landgraf-Karl-Str. 19, 34131 Kassel, Germany
Tel: +49 561 3166797, Fax: +49 561 3166798

Amtsgericht Kassel, HRB 16405
Geschäftsführer: Cornelius Kölbel
signature.asc

Paolo

unread,
Oct 31, 2014, 1:10:51 PM10/31/14
to priva...@googlegroups.com
Now I get this message:

corneliu...@netknights.it

unread,
Oct 31, 2014, 1:12:48 PM10/31/14
to priva...@googlegroups.com
What does your policy look like?

Paolo

unread,
Oct 31, 2014, 1:15:41 PM10/31/14
to priva...@googlegroups.com
scope: gettoken
action: max_count_hotp=1
user: *
realm: testrealm

Cornelius Kölbel

unread,
Oct 31, 2014, 1:20:39 PM10/31/14
to priva...@googlegroups.com
I think I understand why.
Wait a second...
--
You received this message because you are subscribed to the Google Groups "privacyidea" group.
To unsubscribe from this group and stop receiving emails from it, send an email to privacyidea...@googlegroups.com.
To post to this group, send email to priva...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.
signature.asc

Cornelius Kölbel

unread,
Oct 31, 2014, 1:33:18 PM10/31/14
to priva...@googlegroups.com
Confused.

You set this policy:

scope: gettoken
action: max_count_hotp=1
user: *
realm: testrealm

You enrolled an HOTP-token with serial 12345678.

Did you assign the token to a user?

What request are you issuing?

Honestly I can not reproduce it here.

Kind regards
Cornelius
--
You received this message because you are subscribed to the Google Groups "privacyidea" group.
To unsubscribe from this group and stop receiving emails from it, send an email to privacyidea...@googlegroups.com.
To post to this group, send email to priva...@googlegroups.com.
signature.asc

Paolo

unread,
Oct 31, 2014, 1:36:29 PM10/31/14
to priva...@googlegroups.com
I'm issuing these requests:

s = requests.Session()
s.cookies = LWPCookieJar('cookiejar')
s.post('https://localhost:5001/account/dologin?login=' + USER + '&realm=' + REALM + '&password=' + PASSWD, verify=False)
s.get('https://localhost:5001/admin/init?serial=' + SERIAL + '&type=hmac&description=pol_gen&genkey=1&hashlib=sha1&otplen=6&session=' + SESSION_ID, verify=False)
s.get('https://localhost:5001/admin/assign?serial=' + SERIAL + '&user=' + USER_TK + '&session=' + SESSION_ID, verify=False)
s.get('https://localhost:5001/admin/enable?serial=' + SERIAL + '&user=' + USER_TK + '&session=' + SESSION_ID, verify=False)
s.get('https://localhost:5001/gettoken/getotp?serial=' + SERIAL + '&session=' + SESSION_ID, verify=False)

Cornelius Kölbel

unread,
Oct 31, 2014, 3:02:47 PM10/31/14
to priva...@googlegroups.com
Did you define a realm - "the testrealm" - with the USER_TK in it?

For more options, visit https://groups.google.com/d/optout.
signature.asc

corneliu...@netknights.it

unread,
Oct 31, 2014, 8:04:00 PM10/31/14
to priva...@googlegroups.com
Hi Paolo,
I uploaded a new package 1.5dev7 in the ppa dev repository.
This contains a fix for user policies.
Can you try running this?
Thanks a lot

Cornelius

Am Donnerstag, 23. Oktober 2014 17:46:15 UTC+2 schrieb Paolo:

Paolo

unread,
Nov 1, 2014, 3:57:45 AM11/1/14
to priva...@googlegroups.com
wohooooo :D
now it is working perfectly :) :) :)

Thanks a lot Cornelius
Message has been deleted
Message has been deleted

Paolo

unread,
Nov 1, 2014, 4:06:42 AM11/1/14
to priva...@googlegroups.com
I'm sorry it's all ok :) the HOTP value changes when it has been used ;)

Cornelius Kölbel

unread,
Nov 1, 2014, 4:23:28 AM11/1/14
to priva...@googlegroups.com
This is the somehow strange effect of the getotp idea.

You could also set max_count_hotp=30 and request the 30 next HOTP values thus creating some kind of OTP list.
You can do this in the self service portal.

The getotp idea was originally used, when you have a proprietary backend system, that does not allow to authenticate against RADIUS. If the backend system allows to change passwords, than you can issue a getotp request on a DPW (daily changing password) and set the password in the proprietary system. Thus the user could authenticate to the proprietary system with a different password every day.

How do you want to use getotp?

Thanks a lot for your patience. Any feedback is appreciated.

Kind regards
Cornelius
--
You received this message because you are subscribed to the Google Groups "privacyidea" group.
To unsubscribe from this group and stop receiving emails from it, send an email to privacyidea...@googlegroups.com.
To post to this group, send email to priva...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.
signature.asc

Paolo

unread,
Nov 1, 2014, 4:35:20 AM11/1/14
to priva...@googlegroups.com
I got confused between HTOP and TOTP :)
For my purposes (project for a university course) this is perfect, I don't need the extra security of TOTP ;)

Thanks a lot for your help :)

Cornelius Kölbel

unread,
Nov 1, 2014, 4:43:54 AM11/1/14
to priva...@googlegroups.com
yes, but why are you looking at getotp?
I assume that you will use some kind of HOTP tokens which will generate the one time password.
So you do not need to ask privacyidea for the one time password.

The normal workflow would be
1. enroll or import the seed of the hardware token
2. push the button
3. call /validate/check?user=student&pass=secret234765

Kind regards
Cornelius
signature.asc

Paolo

unread,
Nov 1, 2014, 4:55:18 AM11/1/14
to priva...@googlegroups.com
Aaaah ok, you're right :)
I thought that this was the correct way to retrive the token :)
So I have to change the API of ym web service like this:
1) admin/init
2) admin/assign
3) admin/enable
4) enroll so a user can use an app like "freeOTP" to get the token by pushing a button
5) check auth

My problem is how I can implement the point 4. I'm writing this because my project is a python web client which made some get/post requests to various endpoints. So what I would like to know is how I can enroll a token (for using it, for example, with FreeOTP) but without scanning the qrcode (because I have to enroll via terminal)
Thx :)

Cornelius Kölbel

unread,
Nov 1, 2014, 5:19:56 AM11/1/14
to priva...@googlegroups.com
Hi Paolo,

usually you would use the web UI, that comes with privacyIDEA.
Just call https://yourserver/
and login as administrator.

On the left side you see the "enroll" button.
Choose tokentype TOTP and click
[x] the server generates the key.

You will see a QR COde, which you can scan with freeOTP.

If you want the user to do this, you can use the self service portal.
The user logs into the selfservice portal and (you need to define a
policy, what the user is allowed to do in the portal), the user can
enroll a FreeOTP token for and on his own.
(https://privacyidea.org/doc/1.5dev7/policies/selfservice.html)


Kind regards
Cornelius
signature.asc

Paolo

unread,
Nov 1, 2014, 5:29:39 AM11/1/14
to priva...@googlegroups.com
This is the perfect solution :D
Thanks a lot, you helped me a lot!!

If you need something, I'm here ;) (I'm already working on the Italian translation but this will take me some times)

Cornelius Kölbel

unread,
Nov 1, 2014, 5:36:57 AM11/1/14
to priva...@googlegroups.com
Thanks!
As already said, I always appreciate feedback about experiences with the system and how it is used or what is missing.
  <commercial>
  Of course if needed I also provide professional services...
  </commercial>
But of course the great thing is also having people using the system...

Kind regards
Cornelius
--
You received this message because you are subscribed to the Google Groups "privacyidea" group.
To unsubscribe from this group and stop receiving emails from it, send an email to privacyidea...@googlegroups.com.
To post to this group, send email to priva...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.
signature.asc
Reply all
Reply to author
Forward
0 new messages