8 A& ~) }3 ~3 G* I6 L4 H希望通过这个简单、快速的示例,可以让你对应用程序中使用Shiro有个深入的了解。嗯,10分钟你应该可以搞定它。 % b& f E8 S+ i9 E ; w$ l/ e& L0 p概述 / L# _7 k, _: H, [$ D" N! e: y5 l$ G0 G- g
Apache Shiro是什么? # [' `& F, @' t" g9 J' j; n3 d4 d3 O J: m8 v) L
Apache Shiro一个功能强大,使用简单的java安全框架,它为开发人员提供一个直观而全面的认证,授权,加密及会话管理的解决方案。' `6 T J5 E8 L
: u/ `; L/ `/ ~3 `% a实际上,Shiro的主要功能是管理应用程序中与安全相关的全部,同时尽可能支持多种实现方法。Shiro是建立在完善的接口驱动设计和面向对象原则之上的,支持各种自定义行为。Shiro提供的默认实现,使其能完成与其他安全框架同样的功能,这不也是我们一直努力想要得到的吗!, e6 {8 v3 y4 e
" _! C( Y7 G! o ^9 G% B' I
那么Apache Shiro能用来做什么呢?' e6 J; P% Z) a4 s% P0 Q p- X
/ L% `- X1 z; a+ S; w, Z很多,很多,嘿嘿。但是不在快速指南中做介绍,如果你想知道,那怎么办呢?去这里找寻你的答案吧。当然如果你还想知道我们什么时候,以及为什么要"创造"Shiro,去看看Shrio的历史和使命吧。 5 H/ W9 R W) q( u( n) ^, A& i( w, F1 e+ R; H9 ~; u7 ?: }
OK,现在让我们动手做点儿什么吧。4 I2 E# L, o- E
; a. q) X! Y- l8 L
注:Shiro可以在任何环境下运行,小到最简单的命令行应用,大到大型的企业应用以及集群应用。但是我们准备在快速指南中使用最最简单的main方法的方式,让你对Shiro的API有个感官的认识。 6 T; W5 e; N+ I# {6 O, {, c5 P4 B* J' \7 X4 `
下载7 G# d4 `/ R& { c
6 H- M* X- M1 K3 {& s9 K% m, Z1 O确保已经安装了JDK1.5+和Maven2.2+& C: X n5 d! [8 C
去这里下载最新已发布的源码。例子中我们使用1.1.0发布版本。 # E6 D! ^+ w6 y解压源代码0 o. V) r' Z0 D7 s
进入快速指南文件夹2 M2 r" w$ l# q( q0 t$ I
cd shiro-root-1.1.0/samples/quickstart . Q7 c9 U0 V3 o2 `( m7 _+ y / B g5 A7 i+ z. E- A! |0 W1 K7 |运行快速指南0 C8 }% k3 y7 {5 b
mvn compile exec:java) O/ K/ V1 ^) C/ N' X. [0 p
7 [2 _ L, ]! m6 a" R, O过程中会输出日志信息,用来告诉你正在进行的是什么,最后退出执行。可以在这里"samples/quickstart/src/main/java/Quickstart.java "找到源码,也可以进行修改,记得修改后运行"mvn compile exec:java "即可。 9 T7 B& k1 O- o! |& D. X0 K4 Z2 Q$ Z7 q R' ?1 L
Quickstart.java- u8 S# t0 k& | f' g
7 _4 W, W0 V- v8 h ~. f5 DQuickstart.java中包含刚刚我们提到的所有内容(认证、授权等等),通过这个简单的示例可以让你轻松的熟悉Shiro的API。那么,让我们把Quickstart.java中的代码,一点一点剖析,这样便于理解它们的作用。 几乎所有的环境下,都可以通过这种方式获取当前用户:0 [% c) G0 M7 c8 f4 W! u
. Y% {+ ^8 E$ @" z! u3 QSubject currentUser = SecurityUtils.getSubject(); * Q6 }6 k$ F2 R# W : I7 e7 u2 w _通过SecurityUtils.getSubject(),就可以获取当前Subject。Subject是应用中用户的一个特定安全的缩影,虽然感觉上直接使用User会更贴切,但是实际上它的意义远远超过了User。而且每个应用程序都会有自己的用户以及框架,我们可不想和它们混淆在一起,况且Subject就是安全领域公认的名词。OK,我们继续。 9 h) W) Q- d# m: V2 k. y X9 d9 H H# J: a+ J0 o在单应用系统中,调用getSubject()会返回一个Subject,它是位于应用程序中特定位置的用户信息;在服务器中运行的情况下(比如web应用),getSubject会返回一个位于当前线程或请求中的用户信息。 现在你已经得到了Subject对象,那么用它可以做什么呢?% F& o4 c6 `! V; W
x4 r' J+ m1 [" [
如果你想得到应用中用户当前Session的其他参数,可以这样获取Session对象: 1 ?5 L+ _- u0 C . f# |! x6 ]0 Q8 k0 n/ n! JSession session = currentUser.getSession(); 8 I8 @9 u0 }. U+ ]7 T0 g 2 P- R& z% A' }* k* K7 o. @session.setAttribute( "someKey", "aValue" );# Y; Q) {! c. k, t
5 t# W* ?: T9 H* |& C这个Session对象是Shiro中特有的对象,它和我们经常使用的HttpSession非常相似,但还提供了额外的东西,其中与HttpSession最大的不同就是Shiro中的Session不依赖HTTP环境(换句话说,可以在非HTTP 容器下运行)。7 ]/ a2 k, ~ Z; W; c$ {% i
& s- K+ a' S+ _, w
如果将Shiro部署在web应用程序中,那么这个Session就是基于HttpSession的。但是像QuickStart示例那样,在非web环境下使用,Shiro则默认使用EnterpriseSessionManagment。也就是说,不论在应用中的任何一层使用同样的API,却不需要考虑部署环境,这一优点为应用打开一个全新的世界,因为应用中要获取Session对象再也不用依赖于HttpSession或者EJB的会话Bean。而且任何客户端技术都可以共享session 数据。3 y1 a# Z' m4 u% {' S
$ t. O4 {) d e
现在你可以得到当前Subject和它的Session对象。那么我们如何验证比如角色和权限这些东西呢? ' X' o6 E {' _- l0 u) V* i . x; C, q! P6 y1 X* {很简单,可以通过已得到的user对象进行验证。Subject对象代表当前用户,但是,谁才是当前用户呢?他们可是匿名用户啊。也就是说,必须登录才能获取到当前用户。没问题,这样就可以搞定: # G, Q% {/ a: z" n5 C, ?" x/ u+ K+ B7 Z* Q
if ( !currentUser.isAuthenticated() ) { ! F& b: P. a" e # M7 M9 o& N/ s3 G1 g7 D j//collect user principals and credentials in a gui specific manner- e+ X I6 N; J J! ]& C8 K
' a4 @) b+ b) [
//such as username/password html form, X509 certificate, OpenID, etc. + j" [7 t, a; ^5 W _ 7 m& R1 w7 K! E: T//We'll use the username/password example here since it is the most common." V7 |1 O3 N, S5 Z
- P: E4 j' D: _2 f% ^
//(do you know what movie this is from? ;) 1 A+ m3 l* L, l5 _; C7 m' A6 c( c' Z
UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa"); ! w/ L# b- V$ B) E $ Q3 u7 N# z W* m//this is all you have to do to support 'remember me' (no config - built in!):, s* j1 I2 y4 R7 ]( |" a3 F* m