Simple Secure Authentication
Usage
This custom protocol, abbreviated SSA, is offered as alternative to OpenID and OAuth2. It’s not only much simpler but also more secure, in the sense that you cannot do something wrong.
If you wonder why OpenID/OAuth2 is so complex and how this protocol can be so simple, I recommend reading this article TODO!. It dives into the history of the protocols, which explains how the present day situation came to be.
The protocol has three endpoints:
{base-url}/sign-in
{base-url}/profile
{base-url}/sign-out
On one hand, some endpoints and parameters have been especially chosen to differ from OpenID/OAuth2 to avoid confusion. On the other hand, some parameters or responses serving the same purpose are identical.
For static websites
Just redirect to {base-url}/sign-in
to let the user sign-in/up.
By default, once authenticated, the user will be redirected back to the Referer
, the website it comes from.
Now, the are a couple of interesting things in this flow.
First, the authentication state is kept by a cookie. In particular a cookie with the flags HTTP-Only
, Secure
, Path=/profile
and Same-Site=None
.
Each of these flags is important to ensure proper security.
Likewise, the call to /profile
must send the cookie.
Note that this requires special cross-origin request handling server-side in order to set the CORS correctly.
By default, the profile contains only sub
, the anonymized user ID, nickname
and picture
which is an url to the user portrait.
However, more information can be requested using a “scope”?
Likewise, you may want the user to a land on a specific page after signing in. To do that, use the goto
parameter.
For web servers
For this flow, use the callback
parameter. Once signed in, the callback
will be invoked to provide a ticket which can be exchanged for a user profile.
Note that the ticket
is consumed upon usage.
You give a ticket
, you receive the user profile in exchange, that’s it.
The ticket cannot be used anymore afterwards.
For security reasons, the callback
URL must belong to the same domain as the Referer
.
Note that unlike OpenID / OAuth2, you do not to first exchange the “code” for a “token”, before accessing the “userinfo” using the “token”. Instead, you fetch the “profile” directly using the “ticket”.
Also, the callback itself is a POST and not a GET. This improves security by avoiding having the ticket being exposed in the URL, since URLs tend to easely eavesdropped and manipulated.
For terminals / native clients
Native apps, “smart devices” and terminals/shells might not be able to receive incoming requests like a server does, and therefore cannot use the back-end flow. Sometimes, it might not even be possible to show a browser, yet authentication is possible with this flow.
- GET /ticket
{"name":"something-without-a-dot", "scope":"..."}
=>{"code": ..., "ticket": ..., "valid_until": ...}
- Device/user opens browser at /sign-in?code=…
- If
code
is empty, the user will have to enter the code in an input field first - Otherwise, the user will be prompted to authorize the client to access your profile
- Note that permissions will be asked each time since is no means to proove the client’s authenticity
- If
- GET /profile Authorization: Bearer [ticket]
Differences to OpenID
Unlike OpenID allowing global user IDs (the sub
), the SSA protocol imposes the user ID to be “pseudonymous pairwise identifiers”.
In other words, they must differ for each website/client requesting the profile. This is to ensure privacy and it also improves security.
Also, you cannot request a different scope with the avatar. It’s meant to be what is used by default in frontends.
Basically, front-ends are more vulnerable to code injection attacks and client malware. If you want more user information, it should be obtained from the back-end.
Reference
Additional scopes: