认证就是验证用户身份的过程。在认证过程中,用户需要提交实体信息(Principals)和凭据信息(Credentials)以检验用户是否合法。最常见的“实体/凭证”组合便是“用户名/密码”组合。
一、Shiro认证过程
1、收集实体/凭据信息
- //Example using most common scenario of username/password pair:
- UsernamePasswordToken token = new UsernamePasswordToken(username, password);
- //”Remember Me” built-in:
- token.setRememberMe(true);
//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.getPrincipals()获取用户信息。但是它并非是完全认证通过的用户,当你访问需要认证用户的功能时,你仍然需要重新提交认证信息。
这一区别可以参考亚马逊网站,网站会默认记住登录的用户,再次访问网站时,对于非敏感的页面功能,页面上会显示记住的用户信息,但是当你访问网站账户信息时仍然需要再次进行登录认证。
2、提交实体/凭据信息
- Subject currentUser = SecurityUtils.getSubject();
- currentUser.login(token);
Subject currentUser = SecurityUtils.getSubject(); currentUser.login(token);
收集了实体/凭据信息之后,我们可以通过SecurityUtils工具类,获取当前的用户,然后通过调用login方法提交认证。
3、认证处理
- try {
- currentUser.login(token);
- } catch ( UnknownAccountException uae ) { ...
- } catch ( IncorrectCredentialsException ice ) { ...
- } catch ( LockedAccountException lae ) { ...
- } catch ( ExcessiveAttemptsException eae ) { ...
- } ... catch your own ...
- } catch ( AuthenticationException ae ) {
- //unexpected error?
- }
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方法执行过程中抛出异常,那么将认为认证失败。Shiro有着丰富的层次鲜明的异常类来描述认证失败的原因,如代码示例。
二、登出操作
登出操作可以通过调用subject.logout()来删除你的登录信息,如:
- currentUser.logout(); //removes all identifying information and invalidates their session too.
currentUser.logout(); //removes all identifying information and invalidates their session too.
当执行完登出操作后,Session信息将被清空,subject将被视作为匿名用户。
三、认证内部处理机制
以上,是Shiro认证在应用程序中的处理过程,下面将详细解说Shiro认证的内部处理机制。
如上图,我们通过Shiro架构图的认证部分,来说明Shiro认证内部的处理顺序:
1、应用程序构建了一个终端用户认证信息的AuthenticationToken 实例后,调用Subject.login方法。
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方法来编写我们自定义的认证处理。
四、使用多个Realm的处理机制:
1、Authenticator
默认实现是ModularRealmAuthenticator,它既支持单一Realm也支持多个Realm。如果仅配置了一个Realm,ModularRealmAuthenticator 会直接调用该Realm处理认证信息,如果配置了多个Realm,它会根据认证策略来适配Realm,找到合适的Realm执行认证信息。
自定义Authenticator的配置:
- [main]
- ...
- authenticator = com.foo.bar.CustomAuthenticator
- securityManager.authenticator = $authenticator
[main] ... authenticator = com.foo.bar.CustomAuthenticator securityManager.authenticator = $authenticator
2、AuthenticationStrategy(认证策略)
当应用程序配置了多个Realm时,ModularRealmAuthenticator将根据认证策略来判断认证成功或是失败。
例如,如果只有一个Realm验证成功,而其他Realm验证失败,那么这次认证是否成功呢?如果大多数的Realm验证成功了,认证是否就认为成功呢?或者,一个Realm验证成功后,是否还需要判断其他Realm的结果?认证策略就是根据应用程序的需要对这些问题作出决断。
认证策略是一个无状态的组件,在认证过程中会经过4次的调用:
- 在所有Realm被调用之前
- 在调用Realm的getAuthenticationInfo 方法之前
- 在调用Realm的getAuthenticationInfo 方法之后
- 在所有Realm被调用之后
认证策略的另外一项工作就是聚合所有Realm的结果信息封装至一个AuthenticationInfo实例中,并将此信息返回,以此作为Subject的身份信息。
Shiro有3中认证策略的具体实现:
AtLeastOneSuccessfulStrategy | 只要有一个(或更多)的Realm验证成功,那么认证将被视为成功 |
FirstSuccessfulStrategy | 第一个Realm验证成功,整体认证将被视为成功,且后续Realm将被忽略 |
AllSuccessfulStrategy | 所有Realm成功,认证才视为成功 |
ModularRealmAuthenticator 内置的认证策略默认实现是AtLeastOneSuccessfulStrategy 方式,因为这种方式也是被广泛使用的一种认证策略。当然,你也可以通过配置文件定义你需要的策略,如:
- [main]
- ...
- authcStrategy = org.apache.shiro.authc.pam.FirstSuccessfulStrategy
- securityManager.authenticator.authenticationStrategy = $authcStrategy
- ...
[main] ... authcStrategy = org.apache.shiro.authc.pam.FirstSuccessfulStrategy securityManager.authenticator.authenticationStrategy = $authcStrategy ...
3、Realm的顺序
由刚才提到的认证策略,可以看到Realm在ModularRealmAuthenticator 里面的顺序对认证是有影响的。
ModularRealmAuthenticator 会读取配置在SecurityManager里的Realm。当执行认证是,它会遍历Realm集合,对所有支持提交的token的Realm调用getAuthenticationInfo 。
因此,如果Realm的顺序对你使用的认证策略结果有影响,那么你应该在配置文件中明确定义Realm的顺序,如:
- blahRealm = com.company.blah.Realm
- ...
- fooRealm = com.company.foo.Realm
- ...
- barRealm = com.company.another.Realm
- securityManager.realms = $fooRealm, $barRealm, $blahRealm
相关推荐
Apache Shiro中文版使用手册!
Apache Shiro使用手册 共22页.pdf
Apache Shiro使用手册.pdf 学习shiro 入门之用
Apache_Shiro_使用手册(一)Shiro架构介绍
Apache_Shiro_使用手册Apache_Shiro_使用手册Apache_Shiro_使用手册
Apache_Shiro参考手册中文版 Introduction to Apache Shiro What is Apache Shiro? Apache Shiro 是一个强大而灵活的开源安全框架,它干净利落地处理身份认证,授权,企业会话管理和加密。 Apache Shiro 的首要目标...
Shiro核心组件Aplication,Subject,SecurityManager, Realm, Authenticator, Authorizer. 介绍了Shiro认证,授权的实现及其机制原理。给了具体操作步骤及代码。
Apache Shiro 中文手册,想了解权限方面知识的小伙伴们下载吧。
Apache Shiro 开发使用手册,介绍了shiro的架构,认证,授权,实现,配置等,希望能够为大家使用shiro的时候带来帮助。
Apache_Shiro参考手册中文版,官方原版,pdf格式,方便查看,可复制!
ApacheShiro使用手册和Apache Shiro Reference Documentation 该文件下载了别人上传的两个文件,一个10分,一个30分,为了自己以后下载不花那么多分,也不让一些没有多少分的朋友能够下载,所以将别人资源下载后,将...
apache-shiro中文开发技术手册,很实用
shiro文档 java相关项目开发短信功能使用的jar包
apache-shiro-reference《Apache Shiro 参考手册》 Chinese translation of and the other article collection. The laset version of Apache Shiro is 1.5.x. You can also see the demos of the reference at ....
取代spring-security的东西,
Apache-Shiro-使用手册 Apache Shiro 是一个框架,可用于身份验证和授权。本文提供了几个示例用来展示如何在 Java™ 应用程序中使用 Shiro 并给出了如何在一个 Grails web 应用程序中使用它的概述。
Apache_Shiro参考手册中文版-converted
Apache_Shiro_使用手册(四)Realm_实现
授权即访问控制,它将判断用户在应用程序中对资源是否拥有相应的访问权限
认证就是验证用户身份的过程。在认证过程中,用户需要提交实体信息(Principals)和凭据信息(Credentials)以检验用户是否合法。最常见的“实体/凭证”组合便是“用户名/密码”组合