歡迎您光臨本站 註冊首頁

精通 Grails: 身份驗證和授權

←手機掃碼閱讀     火星人 @ 2014-03-12 , reply:0
  
Grails 提供了組成安全 Web 應用程序所需的所有基本構建模塊,包括從簡單的登錄基礎設施到基於角色的授權等各種組件,在本期的 精通 Grails 中,Scott Davis 幫助您通過動手操作保護 Grails 應用程序。您還將了解一些插件,可以幫助您以不同的方式擴展應用程序的安全功能。

在本文中,我將繼續構建一個“微型博客” Blogito。我刪除了此前文章(“用定製 URI 和 codec 優化 Grails 中的 URI”)中的 User,因為 name 欄位是 URI 的重要組成部分。這一次我們將實現完整的 User 子系統。您將理解到如何根據 User 是否登錄啟用登錄、限制用戶行為,甚至根據 User 的角色添加一些授權。

首先,User 需要一種登錄方式,從而能夠發布新的條目。

身份驗證

對於支持多個用戶的博客伺服器來說,進行身份驗證是個好主意。您肯定不希望 John Doe 以 Jane Smith 的身份發布博客條目,不管是有意還是無意。設置身份驗證基礎設施將回答這個問題:“您是誰?”,稍後,您還將添加一些授權機制。授權將回答關於 “允許您做什麼” 的問題。

清單 1 展示了您在 在上一篇文章 中創建的 grails-app/domain/User.groovy 文件:


清單 1. User 類
				  class User {    static constraints = {      login(unique:true)      password(password:true)      name()    }        static hasMany = [entries:Entry]        String login    String password    String name        String toString(){      name    }  }  

login 和 password 欄位已經就緒。您現在只需要提供一個控制器和一個表單。創建 grails-app/controllers/UserController.groovy 並添加如清單 2 所示的代碼:


清單 2. 將 login、authenticate 和 logout 閉包添加到 UserController
				  class UserController {    def scaffold = User        def login = {}        def authenticate = {      def user = User.findByLoginAndPassword(params.login, params.password)      if(user){        session.user = user        flash.message = "Hello ${user.name}!"        redirect(controller:"entry", action:"list")            }else{        flash.message = "Sorry, ${params.login}. Please try again."        redirect(action:"login")      }    }        def logout = {      flash.message = "Goodbye ${session.user.name}"      session.user = null      redirect(controller:"entry", action:"list")          }    }  

空的 login 閉包僅僅表示在您的瀏覽器中訪問 http://localhost:9090/blogito/user/login 將呈現 grails-app/views/user/login.gsp 文件(您稍後即將創建該文件)。

authenticate 閉包使用了一個方便的 GORM 方法(findByLoginAndPassword() )執行需要的操作:在資料庫中查找 User,該 User 的 login 和 password 匹配表單欄位中輸入的值,並通過 params hashmap 使用戶可用。如果 User 存在的話,將它添加到會話中。如果不存在的話,重定向回登錄表單以允許 User 再一次提供正確的憑證。logout 閉包將執行 User 退出,將他或她從會話中刪除,然後重定向回 EntryController 中的 list 操作。

現在讓我們開始創建 login.gsp。可以手動輸入清單 3 中所示的代碼,或者可以執行下面的操作:

  1. 在命令行輸入 grails generate-views User。
  2. 將 create.gsp 複製到 login.gsp。
  3. 簡化生成的代碼。

 


清單 3. login.gsp
				  <html>    <head>      <meta name="layout" content="main" />      <title>Login</title>             </head>    <body>      <div class="body">        <h1>Login</h1>        <g:if test="${flash.message}">          <div class="message">${flash.message}</div>        </g:if>        <g:form action="authenticate" method="post" >          <div class="dialog">            <table>              <tbody>                            <tr class="prop">                  <td class="name">                    <label for="login">Login:</label>                  </td>                  <td>                    <input type="text" id="login" name="login"/>                  </td>                </tr>                             <tr class="prop">                  <td class="name">                    <label for="password">Password:</label>                  </td>                  <td>                    <input type="password" id="password" name="password"/>                  </td>                </tr>               </tbody>            </table>          </div>          <div class="buttons">            <span class="button">              <input class="save" type="submit" value="Login" />            </span>          </div>        </g:form>      </div>    </body>  </html>  

注意,表單的 action 是 authenticate,它匹配 UserController.groovy 中的閉包的名稱。輸入元素( login 和 password )中的名稱對應於 authenticate 閉包中的 params.login 和 params.password。

輸入 grails run-app 並運行您的身份驗證基礎設施。嘗試使用密碼 foo 以 jsmith 的身份登錄(記住在 “用定製 URI 和 codec 優化 Grails 中的 URI” 中,您在 grails-app/conf/BootStrap.groovy 中為 Blogito 提供了一些用戶)。您的登錄將失敗,如圖 1 所示:


圖 1. 失敗的登錄嘗試,顯示錯誤消息

再次以 jsmith 的身份和密碼 wordpass 嘗試登錄。這一次應當成功。

如果歡迎消息沒有出現在 grails-app/views/entry/list.gsp 中 — 並且它不應該出現 — 那麼只需將 <g:if test="${flash.message}"> 塊從 login.gsp 複製到 list.gsp 文件的頂部。再次以 jsmith 身份登錄,檢驗現在是否顯示了如圖 2 所示的消息:


圖 2. 確認成功登錄的 Flash 消息

現在可以確定身份驗證能夠正常工作,應當創建一個 TagLib 來簡化登錄和退出。





創建一個身份驗證 TagLib

像 Google 和 Amazon 這樣的 Web 站點在標題處提供了一個不太顯眼的文本鏈接,允許您登錄和退出。您只需要幾行代碼就可以在 Grails 中實現這一點。

首先,在命令提示下輸入 grails create-tag-lib Login。將清單 4 中的代碼添加到新創建的 grails-app/taglib/LoginTagLib.groovy 中:


清單 4. LoginTagLib.groovy
				  class LoginTagLib {    def loginControl = {      if(session.user){        out << "Hello ${session.user.name} "        out << """[${link(action:"logout", controller:"user"){"Logout"}}]"""      } else {        out << """[${link(action:"login", controller:"user"){"Login"}}]"""            }    }  }  

現在,將新的 <g:loginControl> 標記添加到 grails-app/views/layouts/_header.gsp,如清單 5 所示:


清單 5. 將 <loginControl> 標記添加到標題
				  <div id="header">    <p><g:link class="header-main" controller="entry">Blogito</g:link></p>    <p class="header-sub">A tiny little blog</p>        <div id="loginHeader">      <g:loginControl />    </div>  </div>  

最後,將針對 loginHeader <div> 的一些 CSS 格式添加到 web-app/css/main.css,如清單 6 所示:


清單 6. loginHeader <div> 的 CSS 格式
				  #loginHeader {    float: right;    color: #fff;  }  

重啟 Grails 並以 jsmith 身份登錄后,屏幕應該如圖 3 所示:


圖 3. 實際使用 Login TagLib




[火星人 ] 精通 Grails: 身份驗證和授權已經有498次圍觀

http://coctec.com/docs/linux/show-post-68851.html