) o7 O* q/ W6 G& F' i4 J8 N" O% n如果将Shiro部署在web应用程序中,那么这个Session就是基于HttpSession的。但是像QuickStart示例那样,在非web环境下使用,Shiro则默认使用EnterpriseSessionManagment。也就是说,不论在应用中的任何一层使用同样的API,却不需要考虑部署环境,这一优点为应用打开一个全新的世界,因为应用中要获取Session对象再也不用依赖于HttpSession或者EJB的会话Bean。而且任何客户端技术都可以共享session 数据。# {+ j$ F, i( d) t6 w
1 q, P& C0 N6 E现在你可以得到当前Subject和它的Session对象。那么我们如何验证比如角色和权限这些东西呢? 6 H4 H; s' M: p: Y* I7 h- a5 O Y% k$ U+ `
很简单,可以通过已得到的user对象进行验证。Subject对象代表当前用户,但是,谁才是当前用户呢?他们可是匿名用户啊。也就是说,必须登录才能获取到当前用户。没问题,这样就可以搞定: 5 l' O/ x+ W( q$ U : [ Q' Q' E, z, \: e7 xif ( !currentUser.isAuthenticated() ) { ! f# c" m0 W8 @$ `# a6 q) j- }( X+ e, L/ M
//collect user principals and credentials in a gui specific manner2 m \ _; V) s5 T
+ H) ~0 e6 P8 r# _- r: U/ ]//such as username/password html form, X509 certificate, OpenID, etc.' [* p8 g3 Q. ?6 ~1 L; }; v% W+ p
- X7 F d9 E& s* s2 f; k* N//We'll use the username/password example here since it is the most common.' u6 E) l4 a7 F2 D; {! y
+ k1 v" n6 q( S& K$ D0 H( W//(do you know what movie this is from? ;)! T* X7 l" h8 K( U$ c% G
) ?* F* h% R3 `
UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa");% _2 d; U: Z5 d- g# i
7 f; q- S; a+ M$ ^, ~! m
//this is all you have to do to support 'remember me' (no config - built in!): - Z4 A. E7 A4 P+ ?3 \% R 9 E- P5 p$ e8 e6 t& s( ptoken.setRememberMe(true); ' W N* _3 {/ F( x . [4 u- f1 U3 zcurrentUser.login(token); & \, ]- J c. l4 }* V" y0 V3 d0 C5 f# B3 e: `. [
}! j" |1 i+ f+ _6 t
1 w' h* V- y4 I8 I
就是这样,太简单了吧! x" a, X! Z5 r6 a: j! w4 m3 ?* p
% }& G0 _3 v9 K. F! X0 H& ~那登录失败了怎么处理呢?可以通过捕获各类异常,根据不同类型的异常做出不同的处理:4 f7 |, l* W7 g; J" \5 w
2 M( d( O5 H5 _! [6 D
try {9 U. W% D: r: o$ L
) |+ [- _0 u( J& }: \6 L A//username wasn't in the system, show them an error message? {/ B2 Y+ ]$ e+ y5 [- V+ i# u6 @8 M( v
} catch ( IncorrectCredentialsException ice ) { - ]; l3 Q$ Z. {" a' r& K$ k2 f' M/ t 1 L$ R- l. ], J c//password didn't match, try again?& K8 T8 w! k% |* y
* N6 D6 @& o4 T- R% S
} catch ( LockedAccountException lae ) { - Q, t5 F8 A. u& |$ ` & U- x& v2 q6 j# g//account for that username is locked - can't login. Show them a message?- b" W! H0 O! l9 h6 N; }+ o
0 w! ^+ I4 ]% i4 H' S} / o C5 G, B; R# v1 n1 T. I8 e( b: |. R* p2 _
... more types exceptions to check if you want ...3 M+ Q& V! M5 n
7 W7 M% A D' n} catch ( AuthenticationException ae ) { 0 I: e& G5 ~4 h3 p5 Y- x% U ; \2 n% N8 s, ]4 U" c& Q* I//unexpected condition - error? 5 Y4 Z: |( w; E6 Y3 F' Z7 X( D. _- I7 Z! Q! |
} 5 e" I% A( `- y A( A9 S9 B1 l3 H. v, o4 O: Q! h4 w& P
可以捕获Shiro提供的各种异常,也可以抛出自定义类异常用于处理Shiro未考虑到的情况。预知详情,可以去了解AuthenticationException JavaDoc。, i; ~) A" C- p
' m6 k; o, E9 J" a) D8 [2 S+ U0 z提示:最安全的做法是将登录失败的消息告知用户,你总不会帮助攻击者入侵你的系统吧!4 K6 S# S4 i/ y! J! A
0 m+ w% D5 Y) ?; Q5 _+ M
OK,现在已经拥有一个登录用户了,我们还能做点儿什么呢? , O1 I" `+ C. a0 v+ T. c/ p B) ]. u0 F
比方说,他们是谁:7 J( X: f) a, W0 b
; J) {4 ^9 ]5 U4 X
//print their identifying principal (in this case, a username):' ]: V. @! B7 o* k) j
, r/ K9 t- A- v2 i
log.info( "User [" + currentUser.getPrincipal() + "] logged in successfully." ); ! @+ Q0 f3 d K9 |' u2 \( M . ]9 _, U1 _! @0 F* W! V也可以判断用户是否拥有特定的角色:9 W' H" z' k! O1 @; W! }1 T