作者cyclone350 (老子我最神)
看板java
標題[問題] Java實作security的極限
時間Thu Mar 13 22:44:39 2014
大家好,最近在看設計模式,其中對proxy的一個應用覺得很新奇
但是也有些問題,所以提出來討論!
首先這個應用是基於安全上的考量
應用情境是,程式可以讓使用者下訂單,
訂單下好後,只有下訂單的人(也就是訂單持有人)可以更改訂單
一個訂單可以有以下訊息:商品名稱,商品數量,下訂單使用者
首先我們先訂一個介面 OrderApi,請參考以下網址
https://gist.github.com/anonymous/9528033
之後提供實作 Order class 如下
https://gist.github.com/anonymous/9528024
假如用一般的寫法,我們必須在每次呼叫 set 方法前先檢查改的人是否有權限
(是否為orderUser),當然這方法不是很好...
所以我們可以用動態代理方式來實作,首先我們都在set方法後加上另一個參數
新的介面跟類別分別為 OrderPlusApi, OrderPlus
OrderPlusApi:
https://gist.github.com/anonymous/9528098
OrderPlus :
https://gist.github.com/anonymous/9528541
之後實現 InvocationHandler 介面,讓我們在set時會自動檢查修改者是否為持有者
實現類別為 DynamicProxy
https://gist.github.com/anonymous/9528769
最後我們做一個 Client 類別測試
Client :
https://gist.github.com/anonymous/9529382
最後輸出結果如下:
對不起,李四,您無權修改本訂單資料
李四修改後訂單數量:100
張三修改後訂單數量:123
根據簡單理解,此例應該是應用java的反射機制,而且此例子有個不完美的地方
就是在 set 後要增加 User 參數,在真正的應用程式應該不會讓你帶著User資料趴趴走
有沒有更好的做法?
目前想到的是用 annotation ... 在set前放個annotation,類似validadion一樣
目前有實作的是 JSR250 的 @RolesAllowed 。
以下是改良過的類別
OrderWithAnnotation :
https://gist.github.com/anonymous/9528847
這個意思是,如果要呼叫set方式,就必須是"ROLE_ADMIN"這個使用者才有權限
這可以理解,畢竟應用程式可能是跑在Container底下,例如 spring
所以無須在 set 後面多一個 User 參數
但是有個小問題,@RolesAllowed("ROLE_ADMIN") 是固定的,我們無法根據每一個訂單
設定權限,因為每一個訂單的持有人都不一樣...
如果我必須動態的建立權限,是否有辦法做到? 目前沒看到相對應的解法
因為我並不很瞭解java反射機制的全部... 所以也沒有甚麼 idea 可以透過 annotation
實現。
不知道有沒有更好的作法或是 framework 已經實作了?
另外想請問,如果我們的 java bean 沒有 getter 跟 setter,裡面 member
可能都是 public 讓其他類別可以自由使用。
這種情況java反射機制可以發會作用嗎? 或是Annotation有辦法這樣做嗎?
如果不行,我們可不可以說成
"所有class底下的成員最好都是private並提供getter/setter,
因為這樣的做法可以保持應用程式的整體彈性" ?
標題下得有點奇怪,因為我也沒多研究這方面的技術
請大家多多指教
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 123.193.201.124
→ cyclone350:前面Order的例子是參考王者歸來的書 03/13 22:46
→ qrtt1:為什麼不檢查 order user == current user 就好? 03/14 08:22
→ cyclone350:我想問的就是如何有效果的達到這件事 03/14 08:58
→ qrtt1:session, token, https !? 03/14 09:32
推 Killercat:類似的等價技術叫做Security Token 可以查查看 03/17 13:27