跟我學Shiro 無狀態 Web 應用整合

2021-09-07 10:50:58 字數 3697 閱讀 6580

在一些環境中,可能需要把 web 應用做成無狀態的,即伺服器端無狀態,就是說伺服器端不會儲存像會話這種東西,而是每次請求時帶上相應的使用者名稱進行登入。如一些 rest 風格的 api,如果不使用 oauth2 協議,就可以使用如 rest+hmac 認證進行訪問。hmac(hash-based message authentication code):基於雜湊的訊息認證碼,使用乙個金鑰和乙個訊息作為輸入,生成它們的訊息摘要。注意該金鑰只有客戶端和服務端知道,其他第三方是不知道的。訪問時使用該訊息摘要進行傳播,服務端然後對該訊息摘要進行驗證。如果只傳遞使用者名稱 + 密碼的訊息摘要,一旦被別人捕獲可能會重複使用該摘要進行認證。解決辦法如:

每次客戶端申請乙個 token,然後使用該 token 進行加密,而該 token 是一次性的,即只能用一次;有點類似於 oauth2 的 token 機制,但是簡單些;

客戶端每次生成乙個唯一的 token,然後使用該 token 加密,這樣伺服器端記錄下這些 token,如果之前用過就認為是非法請求。

為了簡單,本文直接對請求的資料(即全部請求的引數)生成訊息摘要,即無法篡改資料,但是可能被別人竊取而能多次呼叫。解決辦法如上所示。

對於伺服器端,不生成會話,而是每次請求時帶上使用者身份進行認證。

@restcontroller

public class servicecontroller

}

當訪問 / hello 服務時,需要傳入 param1、param2 兩個請求引數。

com.github.zhangkaitao.shiro.chapter20.codec.hmacsha256utils:

//使用指定的密碼對內容生成訊息摘要(雜湊值)

public static string digest(string key, string content);

//使用指定的密碼對整個map的內容生成訊息摘要(雜湊值)

public static string digest(string key, mapmap)

對 map 生成訊息摘要主要用於對客戶端 / 伺服器端來回傳遞的引數生成訊息摘要。

public class statelessdefaultsubjectfactory extends defaultwebsubjectfactory 

}

通過呼叫 context.setsessioncreationenabled(false) 表示不建立會話;如果之後呼叫 subject.getsession() 將丟擲 disabledsessionexception 異常。

類似於 formauthenticationfilter,但是根據當前請求上下文資訊每次請求時都要登入的認證過濾器。

public class statelessauthcfilter extends accesscontrolfilter 

protected boolean onaccessdenied(servletrequest request, servletresponse response) throws exception catch (exception e)

return true;

} //登入失敗時預設返回401狀態碼

private void onloginfail(servletresponse response) throws ioexception

}

獲取客戶端傳入的使用者名稱、請求引數、訊息摘要,生成 statelesstoken;然後交給相應的 realm 進行認證。

public class statelesstoken implements authenticationtoken 

public object getcredentials()

}

使用者身份即使用者名稱;憑證即客戶端傳入的訊息摘要。

用於認證的 realm。

public class statelessrealm extends authorizingrealm 

protected authorizationinfo dogetauthorizationinfo(principalcollection principals)

protected authenticationinfo dogetauthenticationinfo(authenticationtoken token) throws authenticationexception

private string getkey(string username)

return null;

}}

此處首先根據客戶端傳入的使用者名稱獲取相應的金鑰,然後使用金鑰對請求引數生成伺服器端的訊息摘要;然後與客戶端的訊息摘要進行匹配;如果匹配說明是合法客戶端傳入的;否則是非法的。這種方式是有漏洞的,一旦別人獲取到該請求,可以重複請求;可以考慮之前介紹的解決方案。

sessionmanager 通過 sessionvalidationschedulerenabled 禁用掉會話排程器,因為我們禁用掉了會話,所以沒必要再定期過期會話了。

每次請求進行認證的***。

/**=statelessauthc

所有請求都將走 statelessauthc ***進行認證。

其他配置請參考源**。

springmvc 學習請參考:

5 分鐘構建 spring web mvc rest 風格 helloworld

跟我學 springmvc

此處使用 springmvc 提供的 resttemplate 進行測試。請參考如下文章進行學習:

spring mvc 測試框架詳解——客戶端測試

spring mvc 測試框架詳解——服務端測試

此處為了方便,使用內嵌 jetty 伺服器啟動服務端:

public class clienttest 

@afterclass

public static void afterclass() throws exception

}

在整個測試開始之前開啟伺服器,整個測試結束時關閉伺服器。

測試成功情況

@test

public void testservicehellosuccess()

對請求引數生成訊息摘要後帶到引數中傳遞給伺服器端,伺服器端驗證通過後訪問相應服務,然後返回資料。

測試失敗情況

}在生成請求引數訊息摘要後,篡改了引數內容,伺服器端接收後進行重新生成訊息摘要發現不一樣,報 401 錯誤狀態碼。

到此,整個測試完成了,需要注意的是,為了安全性,請考慮本文開始介紹的相應解決方案。

5 分鐘構建 spring web mvc rest 風格 helloworld

跟我學 springmvc

spring mvc 測試框架詳解——客戶端測試

spring mvc 測試框架詳解——服務端測試

原文:

《跟我學shiro》系列教程

第一章 shiro簡介 第二章 身份驗證 第三章 授權 第四章 ini配置 第五章 編碼 加密 第六章 realm及相關物件 第七章 與web整合 第八章 機制 第九章 jsp標籤 第十章 會話管理 第十一章 快取機制 第十二章 與spring整合 第十三章 rememberme 第十四章 ssl ...

跟我學Shiro 認識shiro(1)

apache shiro是乙個強大且易用的j a安全框架,執行身份驗證 授權 密碼和會話管理。使用shiro的易於理解的api,您可以快速 輕鬆地獲得任何應用程式,從最小的移動應用程式到最大的網路和企業應用程式。authentication 身份認證 登入,驗證使用者是不是擁有相應的身份 autho...

跟我學XSL XSL入門

跟我學xsl xsl入門 上期我們講到用css 層疊樣式表 來格式化xml文件,其效果並不很令人滿意。實際上css用來格式化html標記比較合適些,只是因為它簡單才在上例中採用。xml在更多的時候只是一種資料檔案,怎樣將它變為我們日常所看到的html格式那樣的檔案呢?如果我們將xml檔案比作結構化的...