日期:2014-05-16 浏览次数:21001 次
3.1.1 示例
Shiro验证Subjects 的过程中,可以分解成三个不同的步骤:
1. 收集Subjects 提交的Principals(身份)和Credentials(凭证);
2. 提交Principals(身份)和Credentials(凭证)进行身份验证;
3. 如果提交成功,则允许访问,否则重新进行身份验证或者阻止访问。
收集身份/凭据信息
//Example using most common scenario of username/password pair: UsernamePasswordToken token = new UsernamePasswordToken(username, password); //”Remember Me” built-in: token.setRememberMe(true); |
UsernamePasswordToken支持最常见的用户名/密码的认证机制。同时,由于它实现了RememberMeAuthenticationToken接口,我们可以通过令牌设置“记住我”的功能。
提交实体/凭据信息
Subject currentUser = SecurityUtils.getSubject(); currentUser.login(token); |
收集了身份/凭据信息之后,我们可以通过SecurityUtils工具类,获取当前的用户,然后通过调用login方法提交认证。
认证处理
try { currentUser.login(token); } catch ( UnknownAccountException uae ) { ... } catch ( IncorrectCredentialsException ice ) { ... } catch ( LockedAccountException lae ) { ... } catch ( ExcessiveAttemptsException eae ) { ... } ... catch your own ... } catch ( AuthenticationException ae ) { //unexpected error? } |
如果login方法执行完毕且没有抛出任何异常信息,那么便认为用户认证通过。之后在应用程序任意地方调用SecurityUtils.getSubject() 都可以获取到当前认证通过的用户实例,使用subject.isAuthenticated()判断用户是否已验证都将返回true。相反,如果login方法执行过程中抛出异常,那么将认为认证失败。
3.1.2 步骤
下面将详细介绍Shiro进行身份认证时的内部处理过程。
如上图,我们通过Shiro架构图的认证部分,来说明Shiro认证内部的处理顺序:
1、应用程序构建了一个终端用户认证信息的AuthenticationToken 实例后,调用Subject.login方法。AuthenticationToken 实例中包含终端用户的Principals(身份信息)和Credentials(凭证信息)。
2、Sbuject的实例通常是DelegatingSubject类(或子类)的实例对象,在认证开始时,会委托应用程序设置的securityManager实例调用securityManager.login(token)方法。
3、SecurityManager接受到token(令牌)信息后会委托内置的Authenticator的实例(通常都是ModularRealmAuthenticator类的实例)调用authenticator.authenticate(token)。ModularRealmAuthenticator在认证过程中会对设置的一个或多个Realm实例进行适配,它实际上为Shiro提供了一个可拔插的认证机制。
4、如果在应用程序中配置了多个Realm,ModularRealmAuthenticator会根据配置的AuthenticationStrategy(认证策略)来进行多Realm的认证过程。在Realm被调用后,AuthenticationStrategy将对每一个Realm的结果作出响应。
注:如果应用程序中仅配置了一个Realm,Realm将被直接调用而无需再配置认证策略。
5、判断每一个Realm是否支持提交的token,如果支持,Realm将调用getAuthenticationInfo(token);getAuthenticationInfo 方法就是实际认证处理,我们通过覆盖Realm的doGetAuthenticationInfo方法来编写我们自定义的认证处理。
3.1.3 配置
Authenticator(认证器)
ShiroSecurityManager 的实现默认使用一个ModularRealmAuthenticator实例。它既支持单一Realm也支持多个Realm。如果仅配置了一个Realm,ModularRealmAuthenticator会直接调用该Realm处理认证信息,如果配置了多个Realm,它会根据认证策略来适配Realm,找到合适的Realm执行认证信息。
如果你想配置SecurityManager通过一个自定义的Authenticator来实现,你可以在shiro.ini 中如下设置:
[main] … authenticator = com.foo.bar.CustomAuthenticator securityManager.authenticator = $authenticator |