这两天学习了一下JAAS,并遇到了一个Tomcat的bug,这里记录下来。
http://java.sun.com/j2se/1.4.2/docs/guide/security/jaas/JAASLMDevGuide.html
这是sun的JAAS developer guide。
开始学习JAAS对于几个概念很混淆,我的习惯是先理大框架,如果大概念不清晰不轻易往下看。找来找去,在callan的博客找到一篇http://callan.iteye.com/blog/158392
,这里的几个例子举得非常贴切
引用
理解这些类和接口的关系我给个生动的比方:一个军事学校,入学的时候校方(LoginModule)根据学生(Subject)的入学通知来确定其合法性,这个过程交由某工作人员(CallbackHandler)执行,(CallbackHandler)确认后,(LoginModule)给不同(Subject)根据其身份发给相关的证件(Principal),有了该证件就可以访问对应的资源,(Subject)根据自己的(Principal)的级别可以使用和访问学校不同资源。
一个(Subject)的(Principal)如果是士官级,那么可以访问的资源就相对少些,如果是将军级那就多些。当然一个(Subject)可以拥有多个(Principal)。
通过分析我们会发现,JAAS采用的也是身份检查+权限分配模式。因此JAAS的应用也分成两个部分:(1)认证;(2)授权。过程是先认证后根据身份来授权(有歧视的嫌疑的东东,本人可是反歧视人士)。
-----------------------------赞叹的分割线--------------------------------------
由于最近在玩tomcat,所以作了几个实验都是基于tomcat的。http://tomcat.apache.org/tomcat-6.0-doc/realm-howto.html给出了几个例子,我试了JDBCRealm和MemoryRealm都没问题。但在试org.apache.catalina.realm.JAASRealm时遇到了问题,tomcat总是报
引用
2009-11-11 13:40:10 org.apache.catalina.realm.JAASRealm parseClassNames
严重: Class tt.User not found! Class not added.
2009-11-11 13:40:10 org.apache.catalina.realm.JAASRealm parseClassNames
严重: Class tt.Role not found! Class not added.
这里 User和Role是extends Principal的POJO.页面也会登录不成功转到403 error
查了一下发现这是tomcat的一个bug https://issues.apache.org/bugzilla/show_bug.cgi?id=44084。 根本原因是以前启动tomcat时JAASReaml不去验证UserClassName和RoleClassName,于是一哥们就报了个bughttps://issues.apache.org/bugzilla/show_bug.cgi?id=40150。修40150的哥们去Class.forName了一把就把状态fix了,结果他没注意所用的ClassLoader(估计UT时用的是Tomcat/lib里面的类),然后Jetspeed的开发者就发现他们的自定义Principal找不到了。
以上不是重点,重点是https://sec1.woopra.com/docs/changelog.html说这个bug在6.0.16中就真正fix了。但我看了一下我的tomcat正是6.0.16啊!又去下了个6.0.20还是有这个问题。
我的解决是,在eclipse的server配置中open luanch configuration->Classpath->User Entries中单独加入这两个类。试了试好了。
没时间去看tomcat这块代码,感觉上这是个没修好的bug?
-----------------------------郁闷的分割线--------------------------------------
几点感想
1) Subject,Principal这两个名字起的超烂
2)LoginModule.login先构造一个Callback(UserNameCallback,PasswordCallback)数组,再由CallbackHandler.handle()去负责获取具体的UserName,Password。看看这里的代码
for (Callback cb : cbs) {
if (cb instanceof NameCallback) {
NameCallback nc = (NameCallback) cb;
nc.setName(userName);
}
if (cb instanceof PasswordCallback) {
PasswordCallback pc = (PasswordCallback) cb;
pc.setPassword(password.toCharArray());
}
}
强转啊强转,bad smell啊bad smell
另外这里感觉像template method更多些。既然CallbackHandler用到强转,说明它已经和LoginModule绑在一起了,既然不能decouple,干脆把Callback去掉,写成这样
class LoginModule{
abstract void readLoginInfo();
}
当然...这样似乎不好重用,而且显得不是很酷。不过到底有多少人会用到DNA验证呢?就算用到多写两句也不会死人吧。这样换来和直觉相一致的设计是否值得?
-----------------------------完结的分割线--------------------------------------
我没有自己去写JAAS Realm,看架势Sun的设计是一个subject能带着不同类型的principal,而org.apache.catalina.realm.JAASRealm只有一个Role,如果我希望有多种维度的权限(比如User同时属于不同的Company和Location)怎么办?自己实现一个JAASRealm吗?
运维网声明
1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网 享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com