2013-06-03 69 views
2

我已經搜索了關於這個主題的教程,但他們都過時了。任何人都可以向我提供任何鏈接,或有關將Spring安全整合到GWT中的示例?GWT與Spring安全框架集成

+0

以下是GWT的單個登錄頁面的一些討論 - 請參閱我的意見以接受答案。我在這裏沒有代碼片段,但今天晚上我會盡力爲您提供。 http://stackoverflow.com/questions/6508238/gwt-authentication-for-some-part-of-application-using-gwt-login-page –

+0

考慮[this](http://stackoverflow.com/questions/13914547/gwt-spring-security-integration-pure-gwt-no-jsp/13934318#13934318)回答如果你有興趣將安全性應用到服務器端方法 –

+0

@PiotrekDe我將等待你的代碼片斷,謝謝 – Olzhas

回答

3

首先,您必須記住,GWT應用程序已轉變爲在客戶端運行的JavaScript,因此您無法真正保護某些資源。所有敏感信息都應該存儲在服務器端(與其他情況一樣,不僅僅是GWT),所以正確的方法是從應用程序服務層的角度思考Spring Security集成,並將該安全與通信協議使用 - 在GWT的情況下,它在大多數情況下是請求工廠。

該解決方案不是非常簡單,但我無法以任何更好的方式做到...任何細化建議都是值得歡迎的。

您需要從創建GWT ServiceLayerDecorator開始,將請求工廠的世界與Spring的世界連接起來。覆蓋createServiceInstance方法以春季服務類的名稱從服務名稱標註值調用和返回該服務的實例(你需要從春天ApplicationContext獲得它):

final Class<?> serviceClass = requestContext.getAnnotation(ServiceName.class).value(); 
return appContext.getBean(serviceClass); 

此外,你需要重寫超invoke(Method, Object...)方法爲了捕獲所有拋出的運行時異常。 如果是Spring Security AccessDeniedException的實例,應該分析捕獲到的異常原因。如果是這樣,應該重新拋出異常原因。在這種情況下,GWT不會將異常序列化爲字符串,而是再次重新拋出異常,因此,調度程序servlet可以通過設置適當的HTTP響應狀態碼來處理異常。所有其他類型的異常將被GWT序列化爲字符串。

其實,你可以只捕獲GWT ReportableException,但不幸的是它有包訪問修飾符(heh ... GWT不是那麼容易擴展)。捕獲所有運行時異常要安全得多(儘管不是很優雅,我們別無選擇) - 如果GWT實現發生更改,此代碼仍可正常工作。

現在你需要插入你的裝飾器。 - 你需要做一個骯髒的黑客和覆蓋要求在工廠的servlet doPost方法改變了方式,如何處理例外

public MyRequestFactoryServlet() { 
    this(new DefaultExceptionHandler(), new SpringServiceLayerDecorator()); 
} 

的最後一件事:您可以通過擴展要求在工廠的servlet和定義您的Servlet構造如下容易做到這一點 - 默認情況下,異常被序列化爲字符串,服務器發送500個狀態碼。並非所有異常都應該導致500 s.c - 例如安全性異常應該導致未經授權的狀態碼。所以,你需要做的是改寫的異常處理機制以下列方式:

catch (RuntimeException e) { 
    if (e instanceof AccessDeniedException) { 
    response.sendError(HttpServletResponse.SC_UNAUTHORIZED); 
    } else { 
    response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); 
    LOG.log(Level.SEVERE, "Unexpected error", e); 
    } 
} 

而是擴展類的,你可以嘗試使用一些「周圍」方面 - 這是在這種情況下,清晰的解決方案。

就是這樣!現在,您可以像往常一樣使用Spring Security註釋(@Secured等等)來註釋您的應用程序服務層。

我知道 - 這一切都很複雜,但Google的請求工廠幾乎不可擴展。夥計們在通信協議方面做了很多工作,但是這個庫的設計很糟糕。當然,客戶端代碼有一些限制(它被編譯爲java腳本),但服務器端代碼可以設計得更好......

+0

今天想法出現在我的腦海中,您如何看待,如果我檢查授權詳細信息,在GWT servlet實施方法之前,請檢查用戶是否爲anonymouse,如果匿名方法將返回null,則在客戶端,我們可以獲得例如,在GWT的servlet中,每個方法都會檢查Authentication auth = SecurityContextHolder.getContext()。getAuthentication();如果它沒有通過身份驗證,則返回null或任何信息到客戶端並通過其處理。這個想法是否可行? – Olzhas