From 7c082abec97e1ca5090a9b5d0956d53549d19a9f Mon Sep 17 00:00:00 2001 From: Matthias Andreas Benkard Date: Sun, 1 Jul 2012 15:11:25 +0200 Subject: Support WebID login for registered users. --- project.clj | 16 ++++++++++++ schema.sql | 7 ++++++ src/mulk/benki/auth.clj | 66 ++++++++++++++++++++++++++++++++++--------------- src/mulk/benki/main.clj | 3 ++- 4 files changed, 71 insertions(+), 21 deletions(-) diff --git a/project.clj b/project.clj index ab0b79e..2798b0f 100644 --- a/project.clj +++ b/project.clj @@ -41,6 +41,9 @@ [org.openid4java/openid4java-xri "0.9.6" :extension "pom"] [org.openid4java/openid4java-infocard "0.9.6" :extension "pom"] [xerces "2.4.0"] ;log4j needs this; OpenID4Java needs log4j + [xerces/xercesImpl "2.10.0"] ;java-rdfa needs this + [org.slf4j/slf4j-jcl "1.6.6"] ;Jena needs this + ;;[org.slf4j/slf4j-log4j12 "1.6.6"] ;doesn't seem to suffice for Jena [org.jsoup/jsoup "1.6.1"] [org.apache.abdera/abdera-parser "1.1.2"] [org.apache.ws.commons.axiom/axiom-api "1.2.12"] @@ -57,7 +60,17 @@ ;;[org.bouncycastle/bctsp-jdk15on "1.46"] ;; Semantic Web/RDF stuff + ;;[net.java.dev.sommer/foafssl "0.3.1" :extension "pom"] + ;; [net.java.dev.sommer/foafssl-verifier "0.3.1"] + ;; [net.java.dev.sommer/foafssl-filter "0.3.1"] + [net.java.dev.sommer/foafssl-verifier "0.5-SNAPSHOT"] + [net.java.dev.sommer/foafssl-verifier-sesame "0.5-SNAPSHOT"] + ;;[com.hp.hpl.jena/jena "2.6.4"] + [net.rootdev/java-rdfa "0.4.2"] + [net.rootdev/java-rdfa-htmlparser "0.4.2" :extension "pom"] + ;;[nu.validator.htmlparser/htmlparser "1.4"] [org.apache.jena/jena-arq "2.9.1"] + [org.apache.jena/jena-core "2.7.1"] [org.apache.jena/jena-tdb "0.9.1"] [org.apache.jena/jena-larq "1.0.0-incubating"] [org.apache.jena/jena-iri "0.9.1"]] @@ -91,6 +104,9 @@ :snapshots false} "scala-releases" ;pegdown {:url "http://scala-tools.org/repo-releases" + :snapshots false} + "apache-releases" + {:url "https://repository.apache.org/content/repositories/releases/" :snapshots false}} :source-path "src" ;;:jvm-opts ["-Xms32m"] diff --git a/schema.sql b/schema.sql index 96b53a3..4170b3b 100644 --- a/schema.sql +++ b/schema.sql @@ -21,6 +21,13 @@ CREATE TABLE openids( FOREIGN KEY("user") REFERENCES users ); +CREATE TABLE webids( + "user" INTEGER NOT NULL, + webid VARCHAR NOT NULL, + PRIMARY KEY(webid), + FOREIGN KEY("user") REFERENCES users +); + CREATE TABLE rsa_keys( modulus NUMERIC NOT NULL, exponent NUMERIC NOT NULL, diff --git a/src/mulk/benki/auth.clj b/src/mulk/benki/auth.clj index b92b3fa..f3e2a95 100644 --- a/src/mulk/benki/auth.clj +++ b/src/mulk/benki/auth.clj @@ -13,7 +13,8 @@ [clojure.java.jdbc :as sql] [com.twinql.clojure.http :as http]) (:import [org.openid4java.consumer ConsumerManager] - [org.openid4java.message ParameterList])) + [org.openid4java.message ParameterList] + [net.java.dev.sommer.foafssl.claims WebIdClaim])) (defonce manager (ConsumerManager.)) @@ -104,6 +105,25 @@ [:script {:type "text/javascript", :src (resolve-uri "/js/openid-login.js")}] )}) +(defn try-webid [cert] + (log (fmt nil "Attempting WebID authentication.")) + (let [webid (second (re-find #"^URI:(.*)" (:subject-alt-name cert))) + modulus (:modulus cert) + exponent (:exponent cert) + pubkey + (.generatePublic (java.security.KeyFactory/getInstance + "RSA") + (java.security.spec.RSAPublicKeySpec. + (BigInteger. (str modulus)) (BigInteger. (str exponent))))] + (log (fmt nil "Verifying WebID: ~a" webid)) + (if (.verify (WebIdClaim. (java.net.URI. webid) pubkey)) + (do + (log "WebID verified!") + (with-dbt + (:user + (query1 "SELECT \"user\" FROM webids WHERE webid = ?" webid)))) + (log "WebID verification failed.")))) + (defpage "/login" [] (let [return-uri (or (session/flash-get ::return-uri) (get-in (request/ring-request) [:headers "referer"]))] @@ -120,23 +140,29 @@ (if return-uri (redirect return-uri) (layout {} "Authenticated!" [:p "Welcome back, " (:first_name cert-user) "!"]))) - (do - (session/flash-put! ::return-uri return-uri) - (layout login-page-layout "Benki Login" - [:div#browserid-box - [:h2 "BrowserID login"] - [:a#browserid {:href "#"} - [:img {:src (resolve-uri "/3rdparty/browserid/sign_in_orange.png") - :alt "Sign in using BrowserID"}]]] - [:div#openid-login-panel - [:h2 "OpenID login"] - [:form {:action (resolve-uri "/login/authenticate"), - :method "GET" - :id "openid_form"} - [:div {:id "openid_choice"} - [:p "Please select your OpenID provider:"] - [:div {:id "openid_btns"}]] - [:div {:id "openid_input_area"} - [:input {:type "text", :name "openid_identifier", :id "openid_identifier"}] - [:input {:type "submit"}]]]])))))) + (if-let [webid-user-id (and *client-cert* (try-webid *client-cert*))] + (let [cert-user (find-user webid-user-id)] + (session/put! :user webid-user-id) + (if return-uri + (redirect return-uri) + (layout {} "Authenticated!" [:p "Welcome back, " (:first_name cert-user) "!"]))) + (do + (session/flash-put! ::return-uri return-uri) + (layout login-page-layout "Benki Login" + [:div#browserid-box + [:h2 "BrowserID login"] + [:a#browserid {:href "#"} + [:img {:src (resolve-uri "/3rdparty/browserid/sign_in_orange.png") + :alt "Sign in using BrowserID"}]]] + [:div#openid-login-panel + [:h2 "OpenID login"] + [:form {:action (resolve-uri "/login/authenticate"), + :method "GET" + :id "openid_form"} + [:div {:id "openid_choice"} + [:p "Please select your OpenID provider:"] + [:div {:id "openid_btns"}]] + [:div {:id "openid_input_area"} + [:input {:type "text", :name "openid_identifier", :id "openid_identifier"}] + [:input {:type "submit"}]]]]))))))) \ No newline at end of file diff --git a/src/mulk/benki/main.clj b/src/mulk/benki/main.clj index bf15e1f..0c2f20f 100644 --- a/src/mulk/benki/main.clj +++ b/src/mulk/benki/main.clj @@ -137,7 +137,8 @@ (defn init-security! [] (java.security.Security/addProvider - (org.bouncycastle.jce.provider.BouncyCastleProvider.))) + (org.bouncycastle.jce.provider.BouncyCastleProvider.)) + (Class/forName "net.java.dev.sommer.foafssl.sesame.verifier.SesameFoafSslVerifier")) (defn -main [& args] (do -- cgit v1.2.3