From: Juliusz Chroboczek <jch@irif.fr> To: galene@lists.galene.org Subject: [Galene] Token authentication Date: Sat, 30 Oct 2021 02:09:02 +0200 [thread overview] Message-ID: <87tugzwezl.wl-jch@irif.fr> (raw) Hi, I think I've got a working prototype of token authentication for Galene. There are still some features missing (for example authentication for recorded files, or finer The configuration file looks like this: { "authServer": "http://localhost:1234", "authKeys": [{ "alg": "HS256", "k": "AQIDBA==" }] } The authServer field is the URL of the authentication server; HTTP is supported, but not recommended -- it's not a good idea to carry passwords in the clear. The authKeys field is an array of (public) keys in JWK format; multiple keys are allowed if they have distinct "kid" fields. Right now, only HS256, HS384 and HS512 are supported, I'll look at public key crypto at some later date. The protocol is as follows. When a client wishes to join a group, it makes a POST request to the address given by authServer with a JSON object that looks like this: {"group": "groupname", "username": "john", "password": "topsecret"} The server receives the request, checks that the username/password is correct for the given group, then builds the following claim: {"sub": "john", "aud": "groupname", "permissions": {"present": true}, "iat": now, "exp": now+30s} It then wraps it in a signed JWT which it sends in reply to the POST request. The client retrieves the encoded token, and dumps it into the "token" field of the "join" request. The server checks the signature of the token, and, if correct, grants the claimed permissions. What follows is a sample authorisation server. #!/usr/bin/python3 import json import jwt from datetime import datetime, timezone, timedelta from aiohttp import web import aiohttp_cors secret = b"\1\2\3\4" users = { "john": "secret", "peter": "secret2", } async def handler(request): body = await request.json() if not ("username" in body and "group" in body and "password" in body): return web.HTTPBadRequest() username = body["username"] if not (username in users) or users[username] != body["password"]: return web.HTTPUnauthorized() now = datetime.now(tz=timezone.utc) token = { "sub": username, "aud": body["group"], "permissions": {"present": True}, "iat": now, "exp": now + timedelta(seconds=30), } signed = jwt.encode(token, secret, algorithm="HS256") return web.Response( headers={"Content-Type": "aplication/jwt"}, body=signed, ) app = web.Application() route = app.router.add_route("POST", "/", handler) cors = aiohttp_cors.setup(app, defaults={ "*": aiohttp_cors.ResourceOptions( expose_headers="*", allow_headers="*", ) }) cors.add(route) web.run_app(app, port=1234)
next reply other threads:[~2021-10-30 0:09 UTC|newest] Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top 2021-10-30 0:09 Juliusz Chroboczek [this message] 2021-10-30 0:11 ` [Galene] " Juliusz Chroboczek
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style List information: https://lists.galene.org/postorius/lists/galene.lists.galene.org/ * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=87tugzwezl.wl-jch@irif.fr \ --to=jch@irif.fr \ --cc=galene@lists.galene.org \ --subject='Re: [Galene] Token authentication' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox