Cleanup
This commit is contained in:
parent
45394fa59c
commit
8636d3f81a
2 changed files with 41 additions and 127 deletions
157
README.md
157
README.md
|
@ -16,47 +16,52 @@ Related documentation:
|
|||
* [RFC6238, TOTP](https://tools.ietf.org/html/rfc6238)
|
||||
* [RFC4120, Kerberos](https://tools.ietf.org/html/rfc4120)
|
||||
|
||||
## Overview
|
||||
## Overview ##
|
||||
|
||||
This repository contains three components:
|
||||
This repository contains...
|
||||
|
||||
* ungleichotp-server: the reference implementation of the ungleichotp server
|
||||
* ungleichotp-client: a sample implementation of an ungleichotp client
|
||||
* ungleichotpserver: the reference implementation of the ungleichotp server
|
||||
* ungleichotpclient.py: a sample implementation of an ungleichotp client
|
||||
|
||||
|
||||
### Overview client ###
|
||||
## Verifying a token using ungleichotpclient.py ##
|
||||
|
||||
An application that lets you enter the triple (realm, name, token) and
|
||||
responds with OK / NOTOK.
|
||||
Assuming you want to verify
|
||||
(name=ipv6only, realm=ungleich-intern, token=498593) is a
|
||||
valid triple and you do have credentials to access ungleich-otp
|
||||
(name=info@ungleich.ch, realm=ungleich-admin, seed=PZKBPTHDGSLZBKIZ),
|
||||
then the following call will verify the token:
|
||||
|
||||
How to use:
|
||||
```
|
||||
UNGLEICHOTPNAME=info@ungleich.ch \
|
||||
UNGLEICHOTPREALM=ungleich-admin \
|
||||
UNGLEICHOTPSEED=PZKBPTHDGSLZBKIZ \
|
||||
UNGLEICHOTPSERVER=http://localhost:8000/ungleichotp/verify/ \
|
||||
python ungleichotpclient.py -n -r ungleich --token 498593
|
||||
```
|
||||
|
||||
You can also veriy using a seed:
|
||||
|
||||
```
|
||||
UNGLEICHOTPNAME=info@ungleich.ch \
|
||||
UNGLEICHOTPREALM=ungleich-admin \
|
||||
UNGLEICHOTPSEED=PZKBPTHDGSLZBKIZ \
|
||||
UNGLEICHOTPSERVER=http://localhost:8000/ungleichotp/verify/ \
|
||||
python ungleichotpclient.py -n -r ungleich --seed CEKXVG3235PO2HDW
|
||||
```
|
||||
|
||||
The client requires pyotp.
|
||||
|
||||
|
||||
## Setup instructions ##
|
||||
## Server Setup instructions ##
|
||||
|
||||
This is a standard django project and thus can be easily setup using
|
||||
|
||||
```
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
To bootstrap the application, you need your very first trusted seed to
|
||||
access the application. You can generate it using
|
||||
|
||||
```
|
||||
to be filled in
|
||||
```
|
||||
|
||||
After that, you can run the application using
|
||||
|
||||
```
|
||||
python manage.py createsuperuser
|
||||
python manage.py runserver
|
||||
```
|
||||
|
||||
The usual instructions on how to setup an https proxy should be followed.
|
||||
|
||||
## Realms ##
|
||||
|
||||
|
@ -84,113 +89,15 @@ them to verify a token of somebody else.
|
|||
|
||||
|
||||
|
||||
## Environment / Configuration (unfinished)
|
||||
## Verify using http POST ##
|
||||
|
||||
- POSTGRES_USERNAME
|
||||
- SECRET_KEY -- random (?)
|
||||
|
||||
|
||||
## Random notes / stuff (unfinished)
|
||||
|
||||
django.db.backends.postgresql
|
||||
django.contrib.admin
|
||||
|
||||
```
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.postgresql',
|
||||
'NAME': 'mydatabase',
|
||||
'USER': 'mydatabaseuser',
|
||||
'PASSWORD': 'mypassword',
|
||||
'HOST': '127.0.0.1',
|
||||
'PORT': '5432',
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Custom auth
|
||||
|
||||
```
|
||||
from django.contrib.auth.models import User
|
||||
from rest_framework import authentication
|
||||
from rest_framework import exceptions
|
||||
|
||||
class ExampleAuthentication(authentication.BaseAuthentication):
|
||||
def authenticate(self, request):
|
||||
username = request.META.get('X_USERNAME')
|
||||
if not username:
|
||||
return None
|
||||
|
||||
try:
|
||||
user = User.objects.get(username=username)
|
||||
except User.DoesNotExist:
|
||||
raise exceptions.AuthenticationFailed('No such user')
|
||||
|
||||
return (user, None)
|
||||
|
||||
```
|
||||
|
||||
Custom user
|
||||
|
||||
Don’t forget to point AUTH_USER_MODEL to it. Do this before creating any migrations or running manage.py migrate for the first time.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### To document
|
||||
|
||||
* Login via username password interactively
|
||||
* Login via name/realm/token rest
|
||||
|
||||
## The library (ungleichotp)
|
||||
|
||||
## The server (ungleichotp-server)
|
||||
|
||||
## The sample client (ungleichotp-client)
|
||||
|
||||
The included client application is a Django application that makes use
|
||||
of an ungleichotp-server to authenticate requests.
|
||||
|
||||
### Usage
|
||||
|
||||
* Ensure that the ungleichotp-server is running and reachable
|
||||
|
||||
|
||||
## Integrating ungleichotp
|
||||
|
||||
### In Django
|
||||
|
||||
|
||||
### In other frameworks
|
||||
|
||||
In general, you will need to implement the following into your app for
|
||||
resources that need to have an authenticated user:
|
||||
|
||||
#### Retrieve name, realm and token from the request
|
||||
|
||||
This is application specific. In the sample Django rest framework, we
|
||||
use JSON to retrieve this values:
|
||||
|
||||
```
|
||||
{
|
||||
"name": "info@ungleich.ch",
|
||||
"token": "947732",
|
||||
"realm": "ungleich-admin",
|
||||
"otherdata": "..."
|
||||
}
|
||||
|
||||
```
|
||||
#### Send name, realm and token from the request to the ungleichotp-server
|
||||
|
||||
Post a JSON object to /ungleichotp/verify that contains the following
|
||||
elements:
|
||||
Post a JSON object to the server at /ungleichotp/verify/ that
|
||||
contains the following elements:
|
||||
|
||||
Request JSON object:
|
||||
|
||||
```
|
||||
{
|
||||
version: "1",
|
||||
name: "your-name",
|
||||
realm: "your-realm",
|
||||
token: "current time based token",
|
||||
|
@ -223,7 +130,7 @@ OR return code 403:
|
|||
{"detail":"You do not have permission to perform this action."}
|
||||
```
|
||||
|
||||
#### Authorize the request
|
||||
## Authorize the request ##
|
||||
|
||||
From the ungleichotp-server, you get a validated information that a
|
||||
name on a realm authenticated successfully. The associated permissions
|
||||
|
|
|
@ -50,7 +50,10 @@ if __name__ == '__main__':
|
|||
parser = argparse.ArgumentParser(description='ungleichotp-client')
|
||||
parser.add_argument('-n', '--name', help="Name (for verification)", required=True)
|
||||
parser.add_argument('-r', '--realm', help="Realm (for verification)", required=True)
|
||||
parser.add_argument('-t', '--token', help="Token (for verification)", required=True)
|
||||
|
||||
g = parser.add_mutually_exclusive_group(required=True)
|
||||
g.add_argument('--token', help="Token (for verification)")
|
||||
g.add_argument('--seed', help="Seed (for verification)")
|
||||
|
||||
args = parser.parse_args(sys.argv[1:])
|
||||
|
||||
|
@ -66,9 +69,13 @@ if __name__ == '__main__':
|
|||
os.environ['UNGLEICHOTPSERVER'])
|
||||
|
||||
|
||||
if args.seed:
|
||||
token = pyotp.TOTP(args.seed).now()
|
||||
else:
|
||||
token = args.token
|
||||
|
||||
try:
|
||||
if client.verify(args.name, args.realm, args.token) == True:
|
||||
if client.verify(args.name, args.realm, token) == True:
|
||||
print("Verify ok")
|
||||
except urllib.error.HTTPError as e:
|
||||
print("Failed to verify: {}".format(e))
|
||||
|
|
Loading…
Reference in a new issue