作者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
1F:→ cyclone350:前面Order的例子是参考王者归来的书 03/13 22:46
2F:→ qrtt1:为什麽不检查 order user == current user 就好? 03/14 08:22
3F:→ cyclone350:我想问的就是如何有效果的达到这件事 03/14 08:58
4F:→ qrtt1:session, token, https !? 03/14 09:32
5F:推 Killercat:类似的等价技术叫做Security Token 可以查查看 03/17 13:27