summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVivien Kraus <vivien@planete-kraus.eu>2020-12-06 20:06:32 +0100
committerVivien Kraus <vivien@planete-kraus.eu>2021-06-19 15:44:36 +0200
commitfeb186bacbf57cb1de4b933eca6f53d259bfcc9d (patch)
tree713ee87f3d576244b77720532beed86b7936f757 /src
parent02a3091aa2ff9d32cad4ffe6eeffabee5e78ca15 (diff)
Implement the resource server verification code
Diffstat (limited to 'src')
-rw-r--r--src/scm/webid-oidc/Makefile.am6
-rw-r--r--src/scm/webid-oidc/resource-server.scm86
2 files changed, 90 insertions, 2 deletions
diff --git a/src/scm/webid-oidc/Makefile.am b/src/scm/webid-oidc/Makefile.am
index 42c65b6..061af17 100644
--- a/src/scm/webid-oidc/Makefile.am
+++ b/src/scm/webid-oidc/Makefile.am
@@ -19,7 +19,8 @@ dist_webidoidcmod_DATA += \
%reldir%/authorization-endpoint.scm \
%reldir%/token-endpoint.scm \
%reldir%/identity-provider.scm \
- %reldir%/provider-confirmation.scm
+ %reldir%/provider-confirmation.scm \
+ %reldir%/resource-server.scm
webidoidcgo_DATA += \
%reldir%/errors.go \
@@ -42,6 +43,7 @@ webidoidcgo_DATA += \
%reldir%/authorization-endpoint.go \
%reldir%/token-endpoint.go \
%reldir%/identity-provider.go \
- %reldir%/provider-confirmation.go
+ %reldir%/provider-confirmation.go \
+ %reldir%/resource-server.go
EXTRA_DIST += %reldir%/ChangeLog
diff --git a/src/scm/webid-oidc/resource-server.scm b/src/scm/webid-oidc/resource-server.scm
new file mode 100644
index 0000000..cef6a0c
--- /dev/null
+++ b/src/scm/webid-oidc/resource-server.scm
@@ -0,0 +1,86 @@
+(define-module (webid-oidc resource-server)
+ #:use-module (webid-oidc errors)
+ #:use-module (webid-oidc oidc-configuration)
+ #:use-module (webid-oidc provider-confirmation)
+ #:use-module (webid-oidc jwk)
+ #:use-module (webid-oidc dpop-proof)
+ #:use-module ((webid-oidc config) #:prefix cfg:)
+ #:use-module (webid-oidc jti)
+ #:use-module (webid-oidc access-token)
+ #:use-module (web request)
+ #:use-module (web response)
+ #:use-module (web uri)
+ #:use-module (web server)
+ #:use-module (web client)
+ #:use-module (ice-9 optargs)
+ #:use-module (ice-9 receive)
+ #:use-module (ice-9 i18n)
+ #:use-module (ice-9 getopt-long)
+ #:use-module (ice-9 suspendable-ports)
+ #:use-module (sxml simple)
+ #:use-module (srfi srfi-19))
+
+(define (G_ text)
+ (let ((out (gettext text)))
+ (if (string=? out text)
+ ;; No translation, disambiguate
+ (car (reverse (string-split text #\|)))
+ out)))
+
+(define*-public (make-authenticator jti-list
+ #:key
+ (server-uri #f)
+ (current-time current-time)
+ (http-get http-get))
+ (unless (and server-uri (uri? server-uri))
+ (error "You need to pass #:server-uri URI where URI is the public URI of the server, as a (web uri)."))
+ (lambda (request request-body)
+ (let ((headers (request-headers request))
+ (uri (request-uri request))
+ (method (request-method request))
+ (current-time
+ (let ((t current-time))
+ (when (thunk? t)
+ (set! t (t)))
+ (when (integer? t)
+ (set! t (make-time time-utc 0 t)))
+ (when (time? t)
+ (set! t (time-utc->date t)))
+ t)))
+ (let ((authz (assoc-ref headers 'authorization))
+ (dpop (assoc-ref headers 'dpop))
+ (full-uri (build-uri (uri-scheme server-uri)
+ #:userinfo (uri-userinfo server-uri)
+ #:host (uri-host server-uri)
+ #:port (uri-port server-uri)
+ #:path (string-append
+ "/"
+ (encode-and-join-uri-path
+ (append
+ (split-and-decode-uri-path (uri-path server-uri))
+ (split-and-decode-uri-path
+ (uri-path uri))))))))
+ (and authz dpop
+ (eq? (car authz) 'dpop)
+ (with-exception-handler
+ (lambda (error)
+ (format (current-error-port)
+ (G_ "~a: authentication failure: ~a\n")
+ (date->string current-time)
+ (error->str error))
+ #f)
+ (lambda ()
+ (let* ((access-token
+ (access-token-decode
+ (symbol->string (cadr authz))
+ #:http-get http-get))
+ (cnf/jkt (access-token-cnf/jkt access-token))
+ (dpop-proof
+ (dpop-proof-decode
+ current-time jti-list method full-uri
+ dpop cnf/jkt)))
+ (let ((subject (access-token-webid access-token))
+ (issuer (access-token-iss access-token)))
+ (confirm-provider subject issuer #:http-get http-get)
+ subject)))
+ #:unwind? #t))))))