您的位置:首页 > 运维架构 > Apache

Apache Shiro 10分钟之旅!

2015-08-30 15:45 603 查看
以下就是对Shiro的简单得学习和了解,如果想要更加深入的学习请参考我的专栏
http://blog.csdn.net/column/details/study-shiro.html?&page=1

前言
欢迎来到ApacheShiro10分钟之旅!
希望通过这个简单、快速的示例,可以让你对应用程序中使用Shiro有个深入的了解。嗯,10分钟你应该可以搞定它。
概述
ApacheShiro是什么?
ApacheShiro一个功能强大,使用简单的Java安全框架,它为开发人员提供一个直观而全面的认证,授权,加密及会话管理的解决方案。
实际上,Shiro的主要功能是管理应用程序中与安全相关的全部,同时尽可能支持多种实现方法。Shiro是建立在完善的接口驱动设计和面向对象原则之上的,支持各种自定义行为。Shiro提供的默认实现,使其能完成与其他安全框架同样的功能,这不也是我们一直努力想要得到的吗!
那么ApacheShiro能用来做什么呢?
很多,很多,嘿嘿。但是不在快速指南中做介绍,如果你想知道,那怎么办呢?去这里找寻你的答案吧。当然如果你还想知道我们什么时候,以及为什么要"创造"Shiro,去看看Shrio的历史和使命吧。
OK,现在让我们动手做点儿什么吧。
注:Shiro可以在任何环境下运行,小到最简单的命令行应用,大到大型的企业应用以及集群应用。但是我们准备在快速指南中使用最最简单的main方法的方式,让你对Shiro的API有个感官的认识。
下载
确保已经安装了JDK1.5+和Maven2.2+
这里下载最新已发布的源码。例子中我们使用1.1.0发布版本。
解压源代码
进入快速指南文件夹cdshiro-root-1.1.0/samples/quickstart
运行快速指南mvncompileexec:java
过程中会输出日志信息,用来告诉你正在进行的是什么,最后退出执行。可以在这里"samples/quickstart/src/main/java/Quickstart.java"找到源码,也可以进行修改,记得修改后运行"mvncompileexec:java"即可。
Quickstart.java
Quickstart.java中包含刚刚我们提到的所有内容(认证、授权等等),通过这个简单的示例可以让你轻松的熟悉Shiro的API。那么,让我们把Quickstart.java中的代码,一点一点剖析,这样便于理解它们的作用。几乎所有的环境下,都可以通过这种方式获取当前用户:
SubjectcurrentUser=SecurityUtils.getSubject();
通过SecurityUtils.getSubject(),就可以获取当前Subject。Subject是应用中用户的一个特定安全的缩影,虽然感觉上直接使用User会更贴切,但是实际上它的意义远远超过了User。而且每个应用程序都会有自己的用户以及框架,我们可不想和它们混淆在一起,况且Subject就是安全领域公认的名词。OK,我们继续。
在单应用系统中,调用getSubject()会返回一个Subject,它是位于应用程序中特定位置的用户信息;在服务器中运行的情况下(比如web应用),getSubject会返回一个位于当前线程或请求中的用户信息。现在你已经得到了Subject对象,那么用它可以做什么呢?
如果你想得到应用中用户当前Session的其他参数,可以这样获取Session对象:
Sessionsession=currentUser.getSession();
session.setAttribute("someKey","aValue");
这个Session对象是Shiro中特有的对象,它和我们经常使用的HttpSession非常相似,但还提供了额外的东西,其中与HttpSession最大的不同就是Shiro中的Session不依赖HTTP环境(换句话说,可以在非HTTP容器下运行)。
如果将Shiro部署在web应用程序中,那么这个Session就是基于HttpSession的。但是像QuickStart示例那样,在非web环境下使用,Shiro则默认使用EnterpriseSessionManagment。也就是说,不论在应用中的任何一层使用同样的API,却不需要考虑部署环境,这一优点为应用打开一个全新的世界,因为应用中要获取Session对象再也不用依赖于HttpSession或者EJB的会话Bean。而且任何客户端技术都可以共享session数据。
现在你可以得到当前Subject和它的Session对象。那么我们如何验证比如角色和权限这些东西呢?
很简单,可以通过已得到的user对象进行验证。Subject对象代表当前用户,但是,谁才是当前用户呢?他们可是匿名用户啊。也就是说,必须登录才能获取到当前用户。没问题,这样就可以搞定:
if(!currentUser.isAuthenticated()){

//collectuserprincipalsandcredentialsinaguispecificmanner

//suchasusername/passwordhtmlform,X509certificate,OpenID,etc.

//We'llusetheusername/passwordexampleheresinceitisthemostcommon.

//(doyouknowwhatmoviethisisfrom?;)

UsernamePasswordTokentoken=newUsernamePasswordToken("lonestarr","vespa");

//thisisallyouhavetodotosupport'rememberme'(noconfig-builtin!):

token.setRememberMe(true);

currentUser.login(token);

}



就是这样,太简单了吧!
那登录失败了怎么处理呢?可以通过捕获各类异常,根据不同类型的异常做出不同的处理:
try{

currentUser.login(token);

//ifnoexception,that'sit,we'redone!

}catch(UnknownAccountExceptionuae){

//usernamewasn'tinthesystem,showthemanerrormessage?

}catch(IncorrectCredentialsExceptionice){

//passworddidn'tmatch,tryagain?

}catch(LockedAccountExceptionlae){

//accountforthatusernameislocked-can'tlogin.Showthemamessage?

}

...moretypesexceptionstocheckifyouwant...

}catch(AuthenticationExceptionae){

//unexpectedcondition-error?

}


可以捕获Shiro提供的各种异常,也可以抛出自定义类异常用于处理Shiro未考虑到的情况。预知详情,可以去了解AuthenticationExceptionJavaDoc。
提示:最安全的做法是将登录失败的消息告知用户,你总不会帮助攻击者入侵你的系统吧!
OK,现在已经拥有一个登录用户了,我们还能做点儿什么呢?
比方说,他们是谁:
//printtheiridentifyingprincipal(inthiscase,ausername):

log.info("User["+currentUser.getPrincipal()+"]loggedinsuccessfully.");
也可以判断用户是否拥有特定的角色:

if(currentUser.hasRole("schwartz")){

log.info("MaytheSchwartzbewithyou!");

}else{

log.info("Hello,meremortal.");

}


还可以判断用户是否对特定某实体有操作权限:
if(currentUser.isPermitted("lightsaber:weild")){

log.info("Youmayusealightsaberring.Useitwisely.");

}else{

log.info("Sorry,lightsaberringsareforschwartzmastersonly.");

}


当然,还可以进行功能强大的实例级别的权限验证。通过它可以判断用户是否有访问特定类型实例的权限:
if(currentUser.isPermitted("winnebago:drive:eagle5")){

log.info("Youarepermittedto'drive'the'winnebago'withlicenseplate(id)'eagle5'."+"Herearethekeys-havefun!");

}else{

log.info("Sorry,youaren'tallowedtodrivethe'eagle5'winnebago!");

}


小菜一碟,对吧。
最后,当用户使用完毕,还可以退出应用。
currentUser.logout();//removesallidentifyinginformationandinvalidatestheirsessiontoo.
这些就是使用ApacheShiro开发应用的核心了,当然,ApacheShiro已将将很多复杂的东西封装在内部了,但是现在它就是这么简单。
你会有疑问吧,用户登录时,谁负责把用户信息(用户名、密码、角色、权限等)取出来,还有运行时,谁负责安全认证呢?当然由你决定了啊。通过将一个实现了Shiro中的Realm的Reaml配置到Shiro中即可。
至于如何配置很大程度上取决于你的运行时环境,比如在单应用、web应用、基于Spring或JEE容器的应用或者组合模式中使用Shiro,配置都有所不同。如何配置已经超出QuickStart示例的范围,因为它的主要目的是帮助你熟悉Shiro的API和概念。
如果想进一步了解Shiro,可以看看AuthenticationGuide和AuthorizationGuide。也可以查看其他文档(特别是ReferenceManual),这里可以解决你的各种疑问。


以上就是对Shiro的简单得学习和了解,如果想要更加深入的学习请参考我的专栏
http://blog.csdn.net/column/details/study-shiro.html?&page=1

本文借鉴:http://www.cnblogs.com/ibook360/archive/2011/10/27/2226522.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: