Loading
Bernard Baker
This is a live streamed presentation. You will automatically follow the presenter and see the slide they're currently on.
@bernardbaker
P0ints addressed in this talk
introduction
a Greek word: αὐθεντικός authentikos, "real, genuine", from αὐθέντης authentes, "author"
introduction
a common problem: user login / API access SFA MFA
introduction
htpasswd
https
OAuth
JWT
history
history
1 | XOR the left half (L) of the data with the r th P-array entry |
2 | Use the XORed data as input for Blowfish's F-function |
3 | XOR the F-function's output with the right half (R) of the data |
4 | Swap L and R |
bcrypt
history
Encoded:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
JWT
Encoded:
header {"alg": "HS256","typ": "JWT"}
payload {"sub": "1234567890","name": "John Doe", "iat": 1516239022}
verify signature
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
your-256-bit-secret
)
The OAuth 2.0 authorization framework enables a third-party application to obtain limited access to an HTTP service.
history
Protocol Flow +--------+ +---------------+ | |--(A)- Authorization Request ->| Resource | | | | Owner | | |<-(B)-- Authorization Grant ---| | | | +---------------+ | | | | +---------------+ | |--(C)-- Authorization Grant -->| Authorization | | Client | | Server | | |<-(D)----- Access Token -------| | | | +---------------+ | | | | +---------------+ | |--(E)----- Access Token ------>| Resource | | | | Server | | |<-(F)--- Protected Resource ---| | +--------+ +---------------+
Passwordless authentication is a type of authentication where users do not need to log in with passwords. This form of authentication totally makes passwords obsolete.
With this form of authentication, users are presented with the options of either logging in simply via a magic link, fingerprint, or using a token that is delivered via email or text message.
history
use case: problem
use case: problem
use case: problem
OpenID Connect
JWT RFC
use case: solution
OpenID Connect 1.0 is a simple identity layer on top of the OAuth 2.0 protocol.
It enables Clients to verify the identity of the End-User based on the authentication performed by an Authorization Server, as well as to obtain basic profile information about the End-User in an interoperable and REST-like manner.
use case: solution
JSON Web Token (JWT) is a compact, URL-safe means of representing claims to be transferred between two parties.
The claims in a JWT are encoded as a JSON object that is used as the payload of a JSON Web Signature (JWS) structure or as the plaintext of a JSON Web Encryption (JWE) structure, enabling the claims to be digitally signed or integrity protected with a Message Authentication Code (MAC) and/or encrypted.
use case: solution
solution provider
implementation
implementation
implementation
HTML & JS
React JS
Netlify serverless functions
code snippets & walkthrough
code snippets & walkthrough
<button id="magic-link">Login</button>
<script src="//cdn.auth0.com/js/lock/11.12.1/lock.min.js"></script>
<script type="text/javascript">
var lockPasswordless = new Auth0LockPasswordless('YOUR_CLIENT_ID', 'YOUR_DOMAIN');
document.getElementById('magic-link').addEventListener('click', function () {
lockPasswordless.show({
passwordlessMethod: 'link'
});
});
</script>
code snippets & walkthrough
let clientId, domain, options;
const [lock, setLock] = useState();
const [baseURI, setBaseURI] = useState();
const [session, setSession] = useState(false);
const initialise = () => {
if (process.env.REACT_APP_ENV === "development") {
setBaseURI("http://localhost:8888/");
} else {
setBaseURI("https://your.domain.com/");
}
clientId = process.env.REACT_APP_CLIENT_ID;
domain = process.env.REACT_APP_DOMAIN;
options = {
closable: true,
passwordlessMethod: "code",
allowedConnections: ["email"],
autofocus: true,
rememberLastLogin: true,
auth: {
audience: "https://your-domain-audience",
responseType: "token"
},
languageDictionary: {
title: "your.domain.com"
},
theme: {
primaryColor: "rgb(255, 0, 0)"
}
};
const lock = new Auth0LockPasswordless(clientId, domain, options);
if (localStorage.getItem("access_token")) {
lock.getUserInfo(localStorage.getItem("access_token"), function(error, profile) {
if (error) console.log("error", error);
setSession(true);
});
}
setLock(lock);
};
const login = () => {
checkSession();
};
const logout = () => {
lock.logout({ returnTo: baseURI });
localStorage.removeItem("access_token");
};
const checkSession = () => {
lock.checkSession({}, function(error, authResult) {
if (error || !authResult) {
lock.show();
} else {
// user has an active session, so we can use the accessToken directly.
lock.getUserInfo(authResult.accessToken, function(error, profile) {
if (error) console.log("error", error);
localStorage.setItem("access_token", authResult.accessToken);
setSession(true);
});
}
});
};
useEffect(() => {
if (!lock) {
initialise();
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
code snippets & walkthrough
import { verify } from "jsonwebtoken";
import JwksRsa from "jwks-rsa";
// Docs on event and context https://www.netlify.com/docs/functions/#the-handler-method
exports.handler = function(event, context, callback) {
const ref = this;
ref.callback = callback;
try {
const token = event?.headers?.bearer;
if (!token) {
throw Error("problem wih authentication token");
}
const options = {
audience: "https://your-domain-audience",
algorithm: ["RS256"],
complete: true
};
var client = JwksRsa({
jwksUri: "https://your-domain-xxx-xxxxxx.xx.auth0.com/.well-known/jwks.json"
});
function getKey(header, callback) {
client.getSigningKey(header.kid, function(err, key) {
var signingKey = key.publicKey || key.rsaPublicKey;
callback(null, signingKey);
});
}
verify(token, getKey, options, (err, decoded) => {
if (err) {
return ref.callback(err, {
statusCode: 401,
body: JSON.stringify({ msg: "Error" })
});
}
ref.callback(null, {
statusCode: 200,
body: JSON.stringify({ msg: "ok" })
});
});
} catch (err) {
ref.callback(err, {
statusCode: 500,
body: err.toString()
});
}
};
it's quick and easy to implement
reliable and broadly adopted
good level of community support
final words & resources
final words & resources