AJ ONeal
2 years ago
13 changed files with 222 additions and 4 deletions
@ -0,0 +1,19 @@ |
|||
{ |
|||
"keys": [ |
|||
{ |
|||
"crv": "P-256", |
|||
"kid": "tsb1m6h3xjp1HjXmJY_8pTtHxld5UvWxoPG9b2e_0aY", |
|||
"kty": "EC", |
|||
"use": "sig", |
|||
"x": "VSQ5P-nwzOMVYowySPF8-FFRTLGXfY611ErayGgM4cc", |
|||
"y": "qSVv69YEJdM7waa_w8wegsaFDZaFZNkRNV-2PUGXb_E" |
|||
}, |
|||
{ |
|||
"e": "AQAB", |
|||
"kid": "dS08lAcJu_zmqIFkBwbI7rgi4OGlaF3uugjs6NysFEY", |
|||
"kty": "RSA", |
|||
"n": "q0yq8t-8Sw9nAJQAbDhiUMtxD_OEHigOekZrcLR38JkagqUZlxYZNp1B7NXM8GTymtz3qKzxUoI-mmE9gHq2nyDN8Jc_DTe_jnNFPD_bAxo92Ii_jpT74_6PR7I92BBvw0-ecxKHScJlO2tD2l1hxyOwpJ52Gt3WuXp2Ezsd3_14boTU4Z3Wh7WFNStz-BBwl09KR8UmVz1_pifJMnDEDXsRMEorFEbSDlJoZLAQgjAEwEZdmecH256WANKGylk1m5PWIBA59FMNXdQZIN1e6Cc0knaqZJHLor1hzmfSjyxxhSck0xk0HccUFNskS9QMoX05IvupxcnMBVPXIQBstw", |
|||
"use": "sig" |
|||
} |
|||
] |
|||
} |
@ -0,0 +1,4 @@ |
|||
{ |
|||
"issuer": "https://therootcompany.github.io/libauth/", |
|||
"jwks_uri": "https://therootcompany.github.io/libauth/.well-known/jwks.json" |
|||
} |
@ -0,0 +1 @@ |
|||
openid-configuration |
@ -0,0 +1,8 @@ |
|||
# Examples |
|||
|
|||
These example RSA and ECDSA private keys can be validated against the demo site: |
|||
|
|||
| Issuer | <https://therootcompany.github.io/libauth/> | |
|||
| :------------ | :-------------------------------------------------------------------------- | |
|||
| Discovery URL | <https://therootcompany.github.io/libauth/.well-known/openid-configuration> | |
|||
| JWKs URL | <https://therootcompany.github.io/libauth/.well-known/jwks.json> | |
@ -0,0 +1,13 @@ |
|||
#!/bin/bash |
|||
|
|||
keypairs sign \ |
|||
--exp 87660h \ |
|||
./examples/privkey.ec.jwk.json \ |
|||
'{ |
|||
"iss": "https://therootcompany.github.io/libauth/", |
|||
"sub": "1", |
|||
"email_verified": false, |
|||
"email": "jo@example.com" |
|||
}' \ |
|||
> ./examples/jwt.txt \ |
|||
2> ./examples/jws.json |
@ -0,0 +1,9 @@ |
|||
module git.rootprojects.org/root/libauth/examples |
|||
|
|||
go 1.18 |
|||
|
|||
require ( |
|||
git.rootprojects.org/root/keypairs v0.6.5 |
|||
git.rootprojects.org/root/libauth v0.1.0 |
|||
github.com/go-chi/chi/v5 v5.0.7 |
|||
) |
@ -0,0 +1,6 @@ |
|||
git.rootprojects.org/root/keypairs v0.6.5 h1:sdRAQD/O/JBS8+ZxUewXnY+cjQVDNH3TmcS+KtANZqA= |
|||
git.rootprojects.org/root/keypairs v0.6.5/go.mod h1:WGI8PadOp+4LjUuI+wNlSwcJwFtY8L9XuNjuO3213HA= |
|||
git.rootprojects.org/root/libauth v0.1.0 h1:qM73YYBLByoFTJUXH2ZeUhJdLzY35t4jgNoUAyqH2QA= |
|||
git.rootprojects.org/root/libauth v0.1.0/go.mod h1:bbLDWn0w7I1VfOMP2DZU/t/H9Ln0mT61K+ELH4ievVM= |
|||
github.com/go-chi/chi/v5 v5.0.7 h1:rDTPXLDHGATaeHvVlLcR4Qe0zftYethFucbjVQ1PxU8= |
|||
github.com/go-chi/chi/v5 v5.0.7/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= |
@ -0,0 +1,18 @@ |
|||
{ |
|||
"claims": { |
|||
"email": "jo@example.com", |
|||
"email_verified": false, |
|||
"exp": 1967702403, |
|||
"iss": "https://therootcompany.github.io/libauth/", |
|||
"sub": "1" |
|||
}, |
|||
"header": { |
|||
"alg": "ES256", |
|||
"kid": "tsb1m6h3xjp1HjXmJY_8pTtHxld5UvWxoPG9b2e_0aY", |
|||
"typ": "JWT" |
|||
}, |
|||
"payload": "eyJlbWFpbCI6ImpvQGV4YW1wbGUuY29tIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJleHAiOjE5Njc3MDI0MDMsImlzcyI6Imh0dHBzOi8vdGhlcm9vdGNvbXBhbnkuZ2l0aHViLmlvL2xpYmF1dGgvIiwic3ViIjoiMSJ9", |
|||
"protected": "eyJhbGciOiJFUzI1NiIsImtpZCI6InRzYjFtNmgzeGpwMUhqWG1KWV84cFR0SHhsZDVVdld4b1BHOWIyZV8wYVkiLCJ0eXAiOiJKV1QifQ", |
|||
"signature": "-vezm5OL5c4vlFvvj0Z4HAbX2nAAabO_37w5wMtnD2_OuzTDhM_4wRxzEZ5sdUIJ0rM7gGAv7B3CfGSibr0TJA" |
|||
} |
|||
|
@ -0,0 +1 @@ |
|||
eyJhbGciOiJFUzI1NiIsImtpZCI6InRzYjFtNmgzeGpwMUhqWG1KWV84cFR0SHhsZDVVdld4b1BHOWIyZV8wYVkiLCJ0eXAiOiJKV1QifQ.eyJlbWFpbCI6ImpvQGV4YW1wbGUuY29tIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJleHAiOjE5Njc3MDI0MDMsImlzcyI6Imh0dHBzOi8vdGhlcm9vdGNvbXBhbnkuZ2l0aHViLmlvL2xpYmF1dGgvIiwic3ViIjoiMSJ9.-vezm5OL5c4vlFvvj0Z4HAbX2nAAabO_37w5wMtnD2_OuzTDhM_4wRxzEZ5sdUIJ0rM7gGAv7B3CfGSibr0TJA |
@ -0,0 +1,7 @@ |
|||
{ |
|||
"crv": "P-256", |
|||
"d": "xcwk5FI9QuCK7Ap-aRsjdaHQx6ckoXcgQQ_HQbarUWE", |
|||
"kty": "EC", |
|||
"x": "VSQ5P-nwzOMVYowySPF8-FFRTLGXfY611ErayGgM4cc", |
|||
"y": "qSVv69YEJdM7waa_w8wegsaFDZaFZNkRNV-2PUGXb_E" |
|||
} |
@ -0,0 +1,11 @@ |
|||
{ |
|||
"d": "d3iFUdcRcBhR8mlG0jOQ_mClfkaMwquVTVqH3JdBf6CIiM21R1a2Rwzuyctjn9YIDlJGuHHF7ZHBL9LaHh13-QvcFgymgQV8qFFk3Fx813EZ6UeWsk7eT2lfbNW3pFXyXPnOvNsTWDIogISTUl0GsOkHbgjGvn4yIDJ033y_nVP6MybnTS7Z-bNZj7YUo9srlTUxXLHd8U9r8b5UIWRCyWeOhsxNjiCCOEinmL6dISjKeubpoG6mbBxC7ptglINqVYHu9HxFfOqd-epbQw0Y5DGIvd6iyzbsfmx8DJwXoJ31oyiFMPdgO5kbZbwEDBCxnHBzxH8M3kfYmL5uYRfnYQ", |
|||
"dp": "YAJfR37hBBwaXct4qkY7_pM2hHRtUOwEAq6QiSB24ogWzq8ehPfIAE_Vu1NAPhMVZk_UPt9A8444pUDLGXpe1-Y66TSC9l6x0g4LhX44A0sc6Wh5Cpbjjr77aim5aVf1AyR-SiPkHNY4SGl_VbkBtk6JOTlww5QwDEdbvcl8ugs", |
|||
"dq": "qO8KbV5svwEAdbHiKt0iFts53PQiD1p-XkvAeV4TPJKYfEmkQPqnpfe6pjN-dnl0S_OwdajLvnU_qVXs0Gec8hJHBf6nBuU0DpIxUML1R-aBqnEPH6-tH8pYK-fD0qr20Qr8tkR8hKI5cthOS0wiqh9A7FC4AUZxLgWOFhs0VdE", |
|||
"e": "AQAB", |
|||
"kty": "RSA", |
|||
"n": "q0yq8t-8Sw9nAJQAbDhiUMtxD_OEHigOekZrcLR38JkagqUZlxYZNp1B7NXM8GTymtz3qKzxUoI-mmE9gHq2nyDN8Jc_DTe_jnNFPD_bAxo92Ii_jpT74_6PR7I92BBvw0-ecxKHScJlO2tD2l1hxyOwpJ52Gt3WuXp2Ezsd3_14boTU4Z3Wh7WFNStz-BBwl09KR8UmVz1_pifJMnDEDXsRMEorFEbSDlJoZLAQgjAEwEZdmecH256WANKGylk1m5PWIBA59FMNXdQZIN1e6Cc0knaqZJHLor1hzmfSjyxxhSck0xk0HccUFNskS9QMoX05IvupxcnMBVPXIQBstw", |
|||
"p": "wzVny5EpwoVF_ljD7mxVVk0gjWTfJ2lkXunb5HbpB_1XkY464kptA9WzSa_0kuSegUrcAPL3KrLPx2ZOT9y9Q5q2RLH4MSCm2uarRvYTiKt9LkIdPFH68iUrrt8wAMX4KXA13mwD-hPpdxNB_Dz1qWqaodW_X-zXLEntBv2tUXs", |
|||
"q": "4KUoRNx164BsU8mFRV9fs4ZUm2fR-Z_JxlUj04dOcu4YYxQNmiSSXDUcTxx3-s4gphh1EVBv52eQ9R7tmmu9EEPIMWWbgdG5FclawDbiUuFnH7MsPT71y6NKWoxUfnzBivLgsdymruYUmJltXvH27pPeZoZetuAzzQFfM25ctvU", |
|||
"qi": "GbOKVpISiuLNPYzTSfQv0pYDDKwtdxyRlSPwU-0rjuYdzsTI6p4QRIbb-8pdWDTuBhmOuB3NUGGPRmeLn8187Z1iTsRSy7bjWmwqcXfOtc22En7OfTUhaUn-p83u9-NpFyGIkB8smZ-kV_g3DEwxovWvvcF3bAajvQCNrbqsOLQ" |
|||
} |
@ -0,0 +1,86 @@ |
|||
package main |
|||
|
|||
import ( |
|||
"encoding/json" |
|||
"fmt" |
|||
"net/http" |
|||
"os" |
|||
"strings" |
|||
|
|||
"github.com/go-chi/chi/v5" |
|||
|
|||
"git.rootprojects.org/root/keypairs/keyfetch" |
|||
"git.rootprojects.org/root/libauth" |
|||
"git.rootprojects.org/root/libauth/chiauth" |
|||
) |
|||
|
|||
func main() { |
|||
r := chi.NewRouter() |
|||
|
|||
whitelist, err := keyfetch.NewWhitelist([]string{"https://therootcompany.github.io/libauth/"}) |
|||
if nil != err { |
|||
panic(err) |
|||
} |
|||
|
|||
// Unauthenticated Routes
|
|||
r.Group(func(r chi.Router) { |
|||
r.Post("/api/hello", func(w http.ResponseWriter, r *http.Request) { |
|||
w.Write([]byte(`{ "message": "Hello, World!" }`)) |
|||
}) |
|||
}) |
|||
|
|||
// Authenticated Routes
|
|||
r.Group(func(r chi.Router) { |
|||
tokenVerifier := chiauth.NewTokenVerifier(chiauth.VerificationParams{ |
|||
Issuers: whitelist, |
|||
Optional: true, |
|||
}) |
|||
r.Use(tokenVerifier) |
|||
|
|||
r.Post("/api/users/profile", func(w http.ResponseWriter, r *http.Request) { |
|||
ctx := r.Context() |
|||
jws, ok := ctx.Value(chiauth.JWSKey).(*libauth.JWS) |
|||
if !ok || !jws.Trusted { |
|||
http.Error(w, "Unauthorized", http.StatusUnauthorized) |
|||
return |
|||
} |
|||
|
|||
userID := jws.Claims["sub"].(string) |
|||
|
|||
b, _ := json.MarshalIndent(struct { |
|||
UserID string `json:"user_id"` |
|||
}{ |
|||
UserID: userID, |
|||
}, "", " ") |
|||
w.Write(append(b, '\n')) |
|||
}) |
|||
}) |
|||
|
|||
// ...
|
|||
|
|||
bindAddr := ":3000" |
|||
fmt.Println("Listening on", bindAddr) |
|||
|
|||
fmt.Println("") |
|||
fmt.Println("Try this:") |
|||
fmt.Println("") |
|||
fmt.Println("") |
|||
cwd, _ := os.Getwd() |
|||
fmt.Println(" pushd", cwd) |
|||
fmt.Println("") |
|||
fmt.Println(" my_jwt=\"$(cat ./jwt.txt)\"") |
|||
fmt.Println( |
|||
strings.Join( |
|||
[]string{ |
|||
" curl -X POST http://localhost:3000/api/users/profile", |
|||
" -H \"Authorization: Bearer ${my_jwt}\"", |
|||
" -H 'Content-Type: application/json'", |
|||
" --data-binary '{ \"foo\": \"bar\" }'", |
|||
}, |
|||
" \\\n", |
|||
), |
|||
) |
|||
fmt.Println("") |
|||
|
|||
http.ListenAndServe(bindAddr, r) |
|||
} |
Loading…
Reference in new issue