当前位置: 首页 > 科技观察

爪哇帝国的安全保卫战

时间:2023-03-19 11:49:29 科技观察

1。前言在Java帝国第三代王者的推动下,帝国向臣民提供了一个叫做JavaAuthenticationandAuthorizationService(简称JAAS)的东西,在第四代王者的努力下,JAAS成功进入了JDK和成为标准包的一部分。王者希望JAAS能够统一安全领域,像JDBC一样引发使用狂潮,成为重要的基础设施。他特意设立了一个新的JAAS大臣职位,并任命了自己的心腹来推动这件事情。但希望越大,失望也越大。除了少数有相关利益的豪门不断挥舞旗帜外,臣民对JAAS不屑一顾,用的人也不多。2雷秀才IO部长这天在家无聊,带着忠实的幕僚InputReader出门微博私访,来到了京城一家有名的小酒馆,点了一些精致的菜品和一壶美酒.还没吃,就看到邻桌一个书生在叹气。IO部长心里一动,就叫他过来聊聊。原来那书生就是雷秀才。他说家乡的税赋很重,他活不下去。IO部长开始好奇,问这是怎么回事。雷秀才道:“都是贾斯的错。”“贾斯?”“只是认证授权而已!”“认证?授权?”“认证是确定你是谁,通常需要验证对方提供的用户名和密码。授权是确定你可以做什么。比如,你是否可以创建账户,删除用户等。”醒醒,为什么不用官方的JAAS呢,帝国的标准挺好的,比如JDBC。使用起来极其繁琐,大家都不想用。但是JAAS部长不管这些,一直在疯狂宣传JAAS。如果他不使用它,他将被课以重税。先去试探对方的套路。雷秀才压低声音:“实话实说,我家新推出了一套名为JSecurity的认证授权系统,想请京城大人献给陛下,以取代JAAS。““哦?!”IO部长坐直了,这是大事!3JSecurityIO部长和InputReader对视一眼:新的机会来了!在和Thread部长、XML部长、JDBC/JTA部长交手之前,我们来斗杀,你不能占便宜,这一次,你或许可以抢占安全领域!”“简单、灵活、好用!比JAAS好用多了!”雷秀才说。“太抽象了,干点干货吧。IO部长决定打开天窗直言:“实话实说,我是朝廷的IO部长。你不用害怕,我可以帮你发挥威严。““啊?!雷秀才满脸错愕。他没想到会在这里碰到一位高官。看来早上去寺庙拜佛是对的,他连忙站起来行礼:“对不起!”IO部长说:“现在可以谈谈你的JSecurity吗?””雷秀才早有准备,从袖子里掏出两张写满代码的纸,递给IO部长和InputReader:"123456");.login(token);if(currentUser.hasRole("admin")){logger.info("You'reAdministrator!");}if(currentUser.isPermitted("user:delete")){logger.info("Youcandeleteanyusers!becareful!");}currentUser.logout();(友情提示:代码可以左右滑动)IO部长戴上老花镜,举起卷子看了一会良久:“你这里怎么叫Subject?为什么不叫User呢?”“大人,这个Subject是安全领域的一个名词,就是所谓的‘主体’,既可以代表用户,也可以代表程序(网络爬虫等),人老家也觉得这个词有点难理解,想用User这样通俗易懂的词,但是考虑到现在很多系统都有User这个概念,为了避免冲突,就最好称它为Subject。”InputReader问道:“你的登录方式,登录失败怎么办?""其实那个方法会抛出异常,需要应用程序处理。我们提供了很多Exception类来处理各种情况,比如未知账户(UnknownAccountException)、密码错误(IncorrectCredentialsException)、账户被锁定(LockedAccountException)、尝试次数过多(ExcessiveAttemptsException)等等。”IO部长说:“但是当程序向用户提供错误信息时,它必须提供模糊的信息,不能被别有用心的人利用,对吧?”“是的,大人,显示给用户的错误信息一定是模糊的,例如:用户名或密码不正确。雷秀才见IO部长开始深思熟虑,非常高兴。“这里可以判断一个用户有什么角色(Role)和权限(Permission),这个角色和权限有什么直接关系?”InputStream继续追问。》这个比较简单,一个角色可以简单的认为是权限的集合,比如admin这个角色可能有删除用户、查看用户、修改用户等权限,再比如viewer这个角色,可能只有查看用户权限。”“那个user:delete是什么意思?”IO部长眼睛一亮。按照以往法庭斗争的经验,这些细节必须搞清楚,否则被人抓住,上不了法庭。文武大臣表面上不动声色,心里却早已鄙视你了。我不能重蹈JTA大臣的覆辙。雷秀才说:“那是我们定义的一个权限符号规则,格式是这样的:resource:operation:instance,用两个冒号隔开,比如:user:create:U001表示对用户资源进行create操作instanceU001user:create表示对资源进行创建操作,相当于user:create:*user:*:U001表示对用户资源instance01进行所有操作。IO大臣点点头,格式由JSecurity定义,但数据内容需要由应用程序决定。InputReader突然说道:“主人,你还记得提出Java注解的安汉林吗?如果这个JSecurity支持注解就好了。”雷秀才道:“支持支持,那个注解很有用。”@RequiresAuthenticationpublicvoidupdateAccount(AccountuserAccount){//这个方法只有在用户认证后才能执行...}@RequiresPermissions("account:create")publicvoidcreateAccount(Accountaccount){//用户必须有account:create权限//执行这个方法...}@RequiresRoles("admin")publicvoiddeleteUser(Useruser){//只有具有admin角色的用户才能执行这个方法...}IO部长觉得眼睛太多了,耳朵在这里,也不宜??久留,所以他建议回自己家继续商量。4Realm的三人回到了IO大臣府。茶还没端上,InputReader就焦急地问道:“你的代码看起来很简单,但是JSecurity去哪里验证这些用户名、密码、权限和角色呢?”雷秀才眼看着问题越陷越深,越发高兴。看来今天真是遇到贵人了。“大人这真是个好问题,”雷秀才说,“对于每一个应用,这些与安全相关的数据可能存放在不同的地方,可能是文本文件,也可能是数据库,也可能是LDAP服务器。.......数据格式也不一样,有的叫user用户,有的可能叫username,有的叫passwordpassword,有的可能叫pwd...考虑到我们的JSecurity是一个框架,我们要做的只是必须想出一个抽象的概念,这个概念叫做境界,听起来有点奇怪。”雷秀才害羞地笑了笑,继续说道:“这个Realm是一个接口,就像一座桥梁。应用程序特定的数据与我们的JSecurity框架理解的格式相关联!它可以将用户应用程序特定的安全数据转换为JSecurity理解的格式。""是不是每个应用都要像JDBCRealm/LDAPRealm/IniRealm一样提供一个独特的实现类?IO部长表示不满。“不用不用,”雷秀才急忙救火,“为了减轻应用程序的负担,我们的JSecurity框架已经提供了这些默认的实现,您在使用的时候只需要做一些调整就可以了。比如sir,你有一个使用数据库表存储用户名和密码的应用程序,users(id,name,pwd...),你只需要提供一个sql给JDBCRealm,我们的框架就可以自动完成认证。”雷秀才又扔出一张图。InputReader看了这张图,自动凑齐了整个认证流程:1.应用配置使用JDBCRealm(当然必须提供数据库的连接信息)2.应用告诉JSecurity如何获取用户的认证信息.密码根据表中的用户名获取,key为sql:jdbcRealm.authenticationQuery=selectpwdfromuserswherename=?3。用户执行subject.login操作,JSecurity使用SQL查询用户名和密码是否与数据库匹配(注:为了简单起见,这里特意忽略了使用salt对密码进行hash的场景。)对于角色和权限,也可以提供类似的sql让JSeurity从数据库表中获取相关数据:“如果一个应用配置了多个Realms,在认证时我应该做什么?”InputReader继续深挖。雷秀才暗暗佩服InputReader的细心周到,说道:“我们定义了一个接口,叫做AuthenticationStrategy,用来定义如何处理多个Realms的认证。我们也提供了几个默认的实现,比如FirstSuccessfulStrategy,只要你遇到一个RealmSuccessful认证成功;或者AllSuccessfulStrategy,所有Realms都必须认证成功。”InputReader点了点头,看来他们考虑得很周到。显然,也可以为授权定义类似的策略。雷秀才画了一张图来展示认证授权的架构:5会话管理“嗯,我觉得你在认证授权方面做得很好!”IO部长试图总结。“大人,我们还支持一些很吸引人的功能,比如Session管理。”“会话?这不是像Tomcat这样的Web容器所做的吗?”InputReader问。》是的,所以一般来说,如果你想使用Session,你必须有Tomcat和Jetty这样的WebContainer,但是如果你使用我们的JSecurity,你根本不需要Tomcat或Jetty。我们内置的Session是支持的,也就是说,即使是桌面应用程序也可以使用Session:"SubjectcurrentUser=SecurityUtils.getSubject();Sessionsession=currentUser.getSession();session.setAttribute("someKey",someValue);"这个主意不错卖点!”InputReader向IO部长使了个眼色。“还有什么功能?”IO部长胃口很大。“我们也提供了一些加密的工具。当然,我们也对网页开发提供了强有力的支持。”“大人,属下觉得这个API的设计真的很简单,比JAAS的简洁多了。”.InputReader对IO部长说。6最后,IO部长非常开心,精力充沛,充满正义感。”他铿锵道:“陛下是一代圣贤,却被贾士大臣给骗了,去取一份吧!雷秀才见朝中大臣愿意为自己出头,十分感动。InputReader却拉过IO大臣,淡淡的说道:“大人,这个JAAS是经过两代王者的努力才进入JDK的,完全代表了豪门名门的利益。再说了,JAAS大臣可是王者身边的红人.不可能就这么废了,你要这么玩,肯定会碰壁,还得曲线救国。“曲线救国?””下属建议先把这个JSecurity开源,让它加入著名的民间组织Apache,先让受试者使用,我们暗中资助一下,这么好用的东西肯定会造成气候,等到燎原之时,陛下就不得不让步了,上校大臣很可能会倒台。”IO部长点头表示赞同。第二天,雷秀才被派往Apache,在那里JSeurity更名为Shiro,开始向公众传播。果然,几年后,爱上Shiro的人越来越多,JAAS也就被冷落了。国王见状,只得让驸马大臣回家养老。【本文为专栏作家“刘欣”原创稿件,转载请通过作者微信获取授权公众号coderising】点此查看该作者更多好文