ivaneye.com

Luminus手册-安全

Security

密码的散列和对比由noir.util.crypt提供。

他提供了两个函数$encrypt$,$compare$.其中第一个函数加密密码,而第二个则是对比密码。实际上加密是通过BCrypt来处理的。

对比代码的函数看起来像这样:

(compare raw encrypted)

加密函数可以自定义salt,或者就不使用salt加密。

(encrypt salt raw)
(encrypt raw)

想了解Secutiry库的更多内容,请点击这里

LDAP Authentication

下面的列子演示了如何通过clj-ldap来验证sAMAccountName

首先,我们先添加依赖

[org.clojars.pntblnk/clj-ldap "0.0.9"]

接下来,我们需要引入authentication命名空间

(ns ldap-auth
  (:require [clj-ldap.client :as client]))

我们可以像下面这样定义LDAP主机。注意host键指向一个Vector。这个Vector里可以包含多个LDAP服务。

(def host
  {:host
    [{:address "my-ldap-server.ca"
      :port 389
      :connect-timeout (* 1000 5)
      :timeout (* 1000 30)}]})

最后我们可以编写一个函数使用上面的LDAP来验证

(defn authenticate [username password & [attributes]]
  (let [server (client/connect host)
        qualified-name (str username "@" (-> host :host first :address))]
    (if (client/bind? server qualified-name  password)
      (first (client/search server "OU=MyOrgPeople,DC=myorg,DC=ca"
                            {:filter (str "sAMAccountName=" username)
                             :attributes (or attributes [])})))))

属性Vector可以用来过滤返回值,如果所有的验证都通过,则返回空Vector

Cross Site Request Forgery Protection

CSRF攻击是第三方通过拦截已登录的用户来操作你的网站的一个攻击。此攻击一般通过你的网站的恶意链接,表单提交或js来进行攻击。

Ring-Anti-Forgery使用来防止CSRF攻击的。只需要引入相关命名空间并将mk-defaults设为true即可。

(def app (app-handler
           [home-routes base-routes]
           :middleware (load-middleware)
           ;; set this to true in order to enable CSRF protection
           :ring-defaults (mk-defaults true)
           :access-rules []
           :formats [:json-kw :edn :transit-json]))

当CSRF中间件开启后,一个随机产生的字符串会被绑定到anti-forgery-token上。任何POST请求需要包含__anti-forgery-token。

我们需要先引入anti-forgery。

(require ... [ring.util.anti-forgery :refer [anti-forgery-field]]))

接着,定义一个CSRF标签到我们的初始化函数中:

(defn init
  ...
  (parser/add-tag! :csrf-token (fn [_ _] (anti-forgery-field)))
  ...)

然后在表单中使用:

    <form name="input" action="/login" method="POST">
      { % csrf-token %}
      Username: <input type="text" name="user">
      Password: <input type="password" name="pass">
      <input type="submit" value="Submit">
    </form>

没有包含此token的POST请求会被拦截。服务器响应403"Invalid anti-forgery token"。