summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Andreas Benkard <code@mail.matthias.benkard.de>2012-07-01 15:11:25 +0200
committerMatthias Andreas Benkard <code@mail.matthias.benkard.de>2012-07-01 15:11:25 +0200
commit7c082abec97e1ca5090a9b5d0956d53549d19a9f (patch)
tree3527ffa3ac2c269a38018539327f1a99d206010b
parent22acc50a5aa38b20c13a5fa650c7988d4cb2a677 (diff)
Support WebID login for registered users.
-rw-r--r--project.clj16
-rw-r--r--schema.sql7
-rw-r--r--src/mulk/benki/auth.clj66
-rw-r--r--src/mulk/benki/main.clj3
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