6 d5 v p( `- _9 ]//collect user principals and credentials in a gui specific manner) i8 B8 z) ^2 _* L, ~9 e w( G5 U+ e
( e9 ~, @5 J' x; P/ n//such as username/password html form, X509 certificate, OpenID, etc. * H$ _8 d' s) ]8 Z+ c- d1 ]. r6 b- H- P) g3 q: X
//We'll use the username/password example here since it is the most common.! q! [* i6 R8 z. U& o6 y/ p* c
7 P( Z0 w9 o) _$ ]3 [//(do you know what movie this is from? ;)8 M& J/ {+ q1 i7 c0 R3 f
: M/ L$ C4 I, I# Y) o: k
UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa"); 3 A5 t3 O& j/ l5 T 7 g, E2 \3 V% r- H9 G6 z//this is all you have to do to support 'remember me' (no config - built in!): , N9 i4 v, J& d$ S 4 x; W/ X7 ^3 [ N( X. W9 [7 D% ?token.setRememberMe(true);1 ?, P( g$ a, W/ |2 o( a4 i& L
# ^" k. k: d: O) T: ~
currentUser.login(token);3 h- }9 I" e' I; |" m) _3 \
7 D, [+ q* v; ?4 B* \) I* l8 o
} . b: I9 j9 p5 w' n$ T8 ?7 w+ x+ g. h p a0 Q
就是这样,太简单了吧! . u9 P0 z8 ^" _* P% ^, ]! p ( V7 n" d% c" Y5 x' K, q那登录失败了怎么处理呢?可以通过捕获各类异常,根据不同类型的异常做出不同的处理: 0 k, P5 [3 b2 H W8 G: g/ n' V9 {7 n' H( m
try { 8 S3 | y3 p5 E6 K : R0 L6 M1 b# ^2 a6 J9 ?currentUser.login( token ); 1 y' f7 U+ N) u2 t8 j/ o0 Y0 Y& `3 _) y6 j9 }
//if no exception, that's it, we're done! . v6 K! z2 i) {5 e5 D2 i' l2 v; H! t
} catch ( UnknownAccountException uae ) { $ @( D' I! m0 W, }( u* ? * X" |8 \4 B( g/ e* z0 Z0 r//username wasn't in the system, show them an error message? / F! `, z- ?, a l5 M% ?; {0 } * p3 J' `2 Z" f/ {% I U. i} catch ( IncorrectCredentialsException ice ) { & F& G, T4 [1 u4 w 2 m: }: ~! a5 v2 I2 X) H* Z//password didn't match, try again? , ^( y& D3 k# H) P* _& g2 ^5 g 7 S& j$ D# Y- f9 Q} catch ( LockedAccountException lae ) {8 b- w' q8 p7 I. I, {% V' f
1 {" h7 Z% [' }, ~6 |- a4 K1 k& e//account for that username is locked - can't login. Show them a message? 1 S5 V' s+ @4 j3 x/ P4 }* a7 H1 F" H - N2 K; @5 W4 ~2 q3 K' i( I} ! a+ ?# J; i3 p' R: i& v: Q3 f! ~- A w7 p" |; y
... more types exceptions to check if you want ..." {5 b9 B2 V7 o. K
/ `4 g0 {. Z. MOK,现在已经拥有一个登录用户了,我们还能做点儿什么呢?& U K' k. a3 O v; x- @
' L8 a5 N( [4 C/ J! c" o比方说,他们是谁:, M2 ]$ G/ T _. t% o! v
# I2 a A+ Z' n# R
//print their identifying principal (in this case, a username): 6 m7 e/ |" L& e' w 9 [) Z" L) V0 k' y) plog.info( "User [" + currentUser.getPrincipal() + "] logged in successfully." );& d' K$ S7 f8 D( r9 B4 i
5 i/ B$ l1 S2 x6 P8 z- C0 B也可以判断用户是否拥有特定的角色:: B2 c6 j7 U+ C }# f9 X: ~, U
3 S* l: P& T0 l( V6 t1 pif ( currentUser.hasRole( "schwartz" ) ) { 2 T4 v6 ?! e, D% T( z- ^3 [$ [2 v, b: G+ v$ i
log.info("May the Schwartz be with you!" ); : \7 f" a8 e$ [9 Q) W. X9 M( I; y# d* P! |4 Z9 H: B# Q* Z
} else {0 K+ F) M# M* r& q0 v1 w
; I( n& E( r+ D1 D [log.info( "Hello, mere mortal." );1 n$ h5 r: p3 M) R1 b" ^' x% N( @
+ U B+ G+ J8 Y4 D; p
} 9 [0 T; c/ k7 S 7 [8 B r/ m' p9 b还可以判断用户是否对特定某实体有操作权限:$ F% i8 `, ]% o3 j
6 X# Q4 `# J" T' Q) |5 p1 f
if ( currentUser.isPermitted( "lightsaber:weild" ) ) {8 ]+ s- [# y: b* H$ P$ {+ t ~# I
1 b" ` z# `' T
log.info("You may use a lightsaber ring. Use it wisely."); ' T" I7 t1 S: |* U+ x/ d+ v* R# t' W5 g. ~5 _$ Y% Q2 _
} else {( D1 d9 b$ k( V, c+ X% v
* e/ g/ Z- }7 P7 v$ r1 Nlog.info("Sorry, lightsaber rings are for schwartz masters only."); 4 ]: f# i3 y1 ]: k4 |/ H+ D" Z : _ u; y* s; p {}; D7 m" s$ T7 ?# Q; J' s
, d' ]9 {: v" X& d2 Z当然,还可以进行功能强大的实例级别的权限验证。通过它可以判断用户是否有访问特定类型实例的权限: & U0 ]" Q# k" x+ F! Z3 u# l+ z& r7 ?$ N2 Z
if ( currentUser.isPermitted( "winnebago:drive:eagle5" ) ) { ! g4 B5 Z5 x; _& d: w" m# h" O3 T7 }
log.info("You are permitted to 'drive' the 'winnebago' with license plate (id) 'eagle5'. " +"Here are the keys - have fun!"); + m: g; a3 @ V4 o. v% | 3 C" M2 x4 m; m' P/ {} else { 8 M) B8 V+ S5 ?- D. j! I F% E: Q 2 W. Y8 e- U( X9 a" ?- Ylog.info("Sorry, you aren't allowed to drive the 'eagle5' winnebago!"); 0 o! r& U9 W, m8 i- K- g! r* p, `, v* r& J) F& i% C5 y
} e, _0 O! S" w" z
8 z' L7 ^7 d7 _% b; I8 ~2 h
小菜一碟,对吧。 7 T' z. @3 A: j- K: x . G5 r* q* S! G' E n最后,当用户使用完毕,还可以退出应用。 9 k7 t5 ]8 |( X/ B 4 ?) O, _& @& Z! p& PcurrentUser.logout(); //removes all identifying information and invalidates their session too. ; C; k9 i+ E$ c+ z' S/ | ) K/ f5 }( g7 s% o$ `; _: P; a这些就是使用Apache Shiro开发应用的核心了,当然,Apache Shiro已将将很多复杂的东西封装在内部了,但是现在它就是这么简单。 8 D8 `2 k. m7 B6 i- S" w7 X8 D1 U% o( k% O! k( {
你会有疑问吧,用户登录时,谁负责把用户信息(用户名、密码、角色、权限等)取出来,还有运行时,谁负责安全认证呢?当然由你决定了啊。通过将一个实现了Shiro中的Realm的Reaml配置到Shiro中即可。 " }2 e5 f& w1 ~: B# N 9 r& V& g, X0 Q至于如何配置很大程度上取决于你的运行时环境,比如在单应用、web应用、基于spring或JEE 容器的应用或者组合模式中使用Shiro,配置都有所不同。如何配置已经超出QuickStart示例的范围,因为它的主要目的是帮助你熟悉Shiro的API和概念。# P6 b% u& l# ?$ Y( h
" ^6 k7 h2 Q3 F$ _+ {如果想进一步了解Shiro,可以看看Authentication Guide和Authorization Guide。也可以查看其他文档(特别是Reference Manual),这里可以解决你的各种疑问。 $ y" i- w' R- m, r . D& _) Q9 h& s0 w