şunun yansıması https://github.com/therootcompany/libauth.git
feat(example): add example server
Bu işleme şunda yer alıyor:
ebeveyn
c529b415bc
işleme
70b0af6796
|
@ -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
|
47
README.md
47
README.md
|
@ -1,6 +1,7 @@
|
|||
# [libauth](https://git.rootprojects.org/root/libauth)
|
||||
|
||||
LibAuth for Go - A modern authentication framework that feels as light as a library.
|
||||
LibAuth for Go - A modern authentication framework that feels as light as a
|
||||
library.
|
||||
|
||||
[![godoc_button]][godoc]
|
||||
|
||||
|
@ -27,7 +28,7 @@ import (
|
|||
func main() {
|
||||
r := chi.NewRouter()
|
||||
|
||||
whitelist, err := keyfetch.NewWhitelist([]string{"https://accounts.google.com"})
|
||||
whitelist, err := keyfetch.NewWhitelist([]string{"https://therootcompany.github.io/libauth/"})
|
||||
if nil != err {
|
||||
panic(err)
|
||||
}
|
||||
|
@ -53,11 +54,45 @@ func main() {
|
|||
}
|
||||
```
|
||||
|
||||
How to create a demo token with [keypairs][https://webinstall.dev/keypairs]:
|
||||
|
||||
```bash
|
||||
my_key='./examples/privkey.ec.jwk.json'
|
||||
my_claims='{
|
||||
"iss": "https://therootcompany.github.io/libauth/",
|
||||
"sub": "1",
|
||||
"email_verified": false,
|
||||
"email": "jo@example.com"
|
||||
}'
|
||||
|
||||
keypairs sign \
|
||||
--exp 1h \
|
||||
"${my_key}" \
|
||||
"${my_claims}" \
|
||||
> jwt.txt
|
||||
2> jws.json
|
||||
```
|
||||
|
||||
How to pass an auth token:
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:3000/api/users/profile \
|
||||
-H 'Authorization: Bearer <xxxx.yyyy.zzzz>' \
|
||||
-H 'Content-Type: application/json' \
|
||||
--raw-data '{ "foo": "bar" }'
|
||||
pushd ./examples
|
||||
go run ./server.go
|
||||
```
|
||||
|
||||
```bash
|
||||
my_token="$(cat ./examples/jwt.txt)"
|
||||
|
||||
curl -X POST http://localhost:3000/api/users/profile \
|
||||
-H "Authorization: Bearer ${my_token}" \
|
||||
-H 'Content-Type: application/json' \
|
||||
--data-binary '{ "foo": "bar" }'
|
||||
```
|
||||
|
||||
## Example OIDC Discovery URLs
|
||||
|
||||
- Demo:
|
||||
<https://therootcompany.github.io/libauth/.well-known/openid-configuration>
|
||||
- Auth0: <https://example.auth0.com/.well-known/openid-configuration>
|
||||
- Okta: <https://example.okta.com/.well-known/openid-configuration>
|
||||
- Google: <https://accounts.google.com/.well-known/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)
|
||||
}
|
Yükleniyor…
Yeni konuda referans